home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Technical Documentation / Mac Tech Notes (DocViewer) / Networking / TN-Networking / TN-Networking
Encoding:
Text File  |  1994-07-24  |  1.6 MB  |  4,096 lines  |  [ONLN/HLX2]

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. NW 1 - AppleShare and Old Finders
  2. Networking    
  3. Revised by:        March 1988
  4. Written by:    Bryan Stearns    March 1987
  5. A rumor has been spread that if you use a pre-AppleShare Finder on a workstation to access AppleShare volumes, you can bypass AppleShare’s “access privilege” mechanisms.
  6. This is not true. Access controls are enforced by the server, not by the Finder. If you use an older Finder, you are still prevented (by the server) from gaining access to protected files and folders; however, you will not get the proper user-interface feedback that you would if you were using the correct Finder: for instance, folders on the server will always appear plain white (that is, without the permission feedback you’d normally get), and error messages would not be as explanatory as those from Finders that “know” about AppleShare servers.
  7. Further Reference:
  8. •    AppleShare User’s Guide
  9. NW 2 - AppleTalk Interface Update
  10. Networking    M.NW.AppleTalkInterfaceUpdate
  11. Revised by:        March 1988
  12. Written by:    Bryan Stearns    July 1987
  13. M.NW.HL.AppleTalk announced that we would be moving to a simplified AppleTalk Manager interface. That interface is available now, as part of MPW 2.0 and newer.
  14. Documentation for this new interface is contained in the AppleTalk Manager chapter of Inside Macintosh Volume V. This technical note contains some of the preliminary documentation for this interface and some useful points about information about it, and AppleTalk in general.
  15. The original AppleTalk Pascal Interfaces, known as ABPasIntf, were designed to simplify use of AppleTalk from high-level languages. Instead, they’ve caused us a few compatibility problems. We’ve decided to encourage use of the same interface that assembly-language AppleTalk uses, a parameter-block interface in the same style as the low-level interfaces to the File and Device Managers.
  16. The original calls are still supported (and will be for a while) as an “alternate” interface, but we suggest that you consider moving to the new “preferred” calls. Be warned that use of the original calls may cause compatibility problems with future system software. Also, new protocols (like ASP, the AppleTalk Session Protocol) are only provided with the new interfaces.
  17. The new interface uses parameter blocks like those used by the File and Device Managers; you fill out the call-specific fields of the block, and a small amount of glue code (provided with development environments like MPW) turns the parameter block into a Control call to the appropriate AppleTalk driver.
  18. Most calls have an interface like:
  19.     FUNCTION PSomeCall(thePBPtr: ATPPBptr; asyncFlag: BOOLEAN): OSErr;
  20. The glue fills in the fields csCode and ioRefNum with the appropriate value for the call you’re making.
  21. Synchronous and Asynchronous calls
  22. You can still make calls synchronously (“do it now”) or asynchronously (“start it now, finish it soon”). If you choose to make a call asynchronously, be sure to provide a completion routine in the ioCompletion field (to be called when the call finally finishes), or poll the ioResult field of the parameter block (the call is done if ioResult is less than or equal to 0).
  23. You must not move or dispose of a parameter block before the call finishes; when the call does complete, you are responsible for throwing the parameter block away (if you allocated it using Memory Manager routines). 
  24. Note that the alternate interfaces generated a network event on completion of an asynchronous call; this service is not provided by the preferred interfaces, partly because of future compatibility problems. See M.NW.NoNetEvents for background information.
  25. Packed data structures
  26. Several of the data structures used by the new interfaces are packed; Pascal doesn’t deal well with these structures. Special calls are provided for building LAP and DPP write-data structures, NBP names-table elements, and ATP buffer data structures.
  27. For example, when registering a name (using PRegisterName), you’ll use a NamesTableEntry structure. This structure consists of a few unpacked fields, followed by an entity-name: three strings (representing the object, type, and zone fields of the name) packed together. You can call NBPSetNTE to pack the strings into the NamesTableEntry structure. When you remove the name (PRemoveName), you’ll use the entity-name by itself; you can use NBPSetEntity to pack it in.
  28. Zone Interface Protocol
  29. A function, GetBridgeAddress, is provided to obtain the node ID of a bridge, for use in ZIP transactions (zero is returned if no bridge is present on your network). You make ZIP calls using ATP requests, as described in the Inside AppleTalk chapter on ZIP.
  30. Further Reference:
  31. •    The AppleTalk Manager
  32. •    Inside AppleTalk (for ZIP information)
  33. •    M.NW.HL.AppleTalk
  34. •    M.NW.NoNetEvents
  35. NW 3 - AppleTalk Phase 2 on the Macintosh
  36. Networking    M.NW.AppleTalkPhase2
  37. Revised by:    Sriram Subramanian    December 1989
  38. Written by:    Pete Helme & Sriram Subramanian    August 1989
  39. This Technical Note discusses the new features and calls available with AppleTalk Phase 2.
  40. Changes since August 1989:  Incorporated the ClosePrep and CancelClosePrep transitions and the new control calls to the .MPP driver.
  41. AppleTalk Phase 2 is only available on Macintosh Plus or later Macintosh platforms, and it requires the installation of AppleTalk file V53, or greater.  Both EtherTalk 2.0 and TokenTalk 2.0 automatically install this AppleTalk file.  Developer Technical Support can supply the Phase 2 drivers for development use; however, if you need to include the Phase 2 drivers in your product, you must license them from Software Licensing.  For more information, contact:
  42.             Apple Software Licensing
  43.             Apple Computer, Inc.,
  44.             20525 Mariani Avenue, M/S 38-I
  45.             Cupertino, CA, 95014
  46.             (408) 974-4667
  47.             AppleLink:  SW.LICENSE
  48. What is AppleTalk Phase 2?
  49. AppleTalk Phase 2 contains enhancements to the routing and naming services of AppleTalk.  Among these enhancements is the ability to create AppleTalk networks which support more than 254 nodes, and to do so in a manner that is, to the greatest extent possible, compatible with current AppleTalk implementations and applications.  Multiple zones per network are now supported, and users can choose their machine’s zone.  Benefits include improved network traffic and better router selection.  New calls and features have been implemented with this enhancement and are documented in this Note.
  50. Are AppleTalk Phase 2 Drivers Present?
  51. So you want to use these new calls and features, but can you?  First, one needs to check to see if the node is running AppleTalk Phase 2.  There are two ways this can be accomplished.  The easiest way is to make a _SysEnvirons call and check the returned atDrvrVersNum field.  If this byte is greater than or equal to 53, then AppleTalk Phase 2 drivers are present.  If, for some reason, a _SysEnvirons call is not practical or otherwise not possible, one can check 7 bytes off the device control entry for the .MPP driver for a single byte, which is the driver version (actually the low byte of the qFlags field of DCtlQHdr in the DCE).  Again, if this byte is 53 or greater, AppleTalk Phase 2 is present, and the calls and features outlined in this Note may be used.
  52. Calls to the .MPP Driver
  53. AppleTalk Phase 2 introduces many new variables, and we highly recommend that you use the new GetAppleTalkInfo call instead of looking at MPP globals directly.  In addition, on a Macintosh running the AppleTalk Internet Router software, there may be more than one .MPP driver present.  These additional drivers can be found by walking through the unit table (UTableBase $11C) and looking for drivers named .MPP other than at unit slot 9.  Generally, the only port of interest to you is the user port, reflected in this call as PortID 0 with a refnum of -10.
  54. GetAppleTalkInfo
  55. Parameter Block
  56.     --> 26    csCode    word    ; always GetAppleTalkInfo (258)
  57.     --> 28    Version    word    ; requested info version
  58.     <-- 30    VarsPtr    pointer    ; pointer to well known MPP vars
  59.     <-- 34    DCEPtr    pointer    ; pointer to MPP DCE
  60.     <-- 38    PortID    word    ; port number [0..7]
  61.     <-- 40    Configuration    long    ; 32-bit configuration word
  62.     <-- 44    SelfSend    word    ; non zero if SelfSend enabled
  63.     <-- 46    NetLo    word    ; low value of network range
  64.     <-- 48    NetHi    word    ; high value of network range
  65.     <-- 50    OurAddr    long    ; our 24-bit AppleTalk address
  66.     <-- 54    RouterAddr    long    ; 24-bit address of (last) router
  67.     <-- 58    NumOfPHs    word    ; max. number of protocol handlers
  68.     <-- 60    NumOfSkts    word    ; max. number of static sockets
  69.     <-- 62    NumNBPEs    word    ; max. concurrent NBP requests
  70.     <-- 64    NTQueue    pointer    ; pointer to registered name queue
  71.     <-> 68    *LAlength    word    ; length in bytes of data link addr
  72.     --> 70    *LinkAddr    pointer    ; data link address returned
  73.     --> 74    *ZoneName    pointer    ; zone name returned 
  74.         * for extended networks only
  75. This call is provided to simplify the task of obtaining details about the current AppleTalk network connection.  The following are the parameters which this call returns:
  76. Version    is passed by the caller.  The concept is similar to one used by _SysEnvirons, where a version ID is passed to the function to return a requested level of information.  If the driver cannot respond because this number is too high, paramErr is returned.  The current version number is 1.
  77. VarsPtr    is the pointer to AppleTalk variables.  This points to the well known sysLapAddr and read header area or RHA..  This pointer may not be equal to $2D8 (ABusVars) for other than port 0.
  78. DCEPtr    is a pointer to the driver’s device control entry. See the Device Manager chapters of Inside Macintosh for details.
  79. PortID    is the port number, and it is always zero, unless a router is active and a driver refnum other than -10 is used.
  80. Configuration    is a 32-bit word of configuration flags.  Currently only the following bits are returned:
  81. 31 (SrvAdrBit)    is true if server node-ID was requested at open time.  Note that even if server address is requested, it may be ignored by those ADEVs which do not honor it (i.e., EtherTalk, TokenTalk, etc.).
  82. 30 (RouterBit)    is true if an AppleTalk Internet Router was loaded at system startup.  Note that a router may be loaded, but not active.
  83. 7 (BadZoneHintBit)    is true if the node’s zone name hint is invalid, thus causing a default zone to be selected.
  84. 6 (OneZoneBit)    is true if only one zone is assigned to an extended network.
  85. SelfSend    (the ability for a node to send packets to itself) is non-zero if this feature is currently enabled.
  86. NetLo    is the low value of the network range.  Non-extended networks always have a range of exactly one network, if the network number is known.
  87. NetHi    is the high value of the network range.
  88. OurAddr    is the 24-bit AppleTalk network address of the node.  The most significant byte is always zero.
  89. RouterAddr    is the 24-bit AppleTalk address of the router from which we last heard.  Users should always use this address when attempting to communicate directly with a router.
  90. NumOfPHs,    are maximum capacities for the driver.  They are number of protocol
  91. NumOfSkts, and    handlers, number of static sockets, and number of concurrent NBP
  92. NumNBPEs    requests allowed, respectively.
  93. NTQueue    is a pointer to the registered names table queue.  See Inside Macintosh, Volume II, The AppleTalk Manager, for NT Queue details.
  94. LALength    is passed by the caller to indicate how much (if any) of the data link address is to be copied to a user-suppled buffer (pointed to by LinkAddr).  The actual length is returned by the driver.  If the caller requests more bytes than the actual number, then data in the buffer after the address is undefined.  The caller is responsible for providing sufficient buffer space.
  95. LinkAddr    is a pointer to a user-supplied buffer into which the data link address data is copied.  If the pointer is NIL, no data is copied.
  96. ZoneName    is a pointer to a user-supplied buffer into which the node’s stored zone name is copied.  If the pointer is NIL, no data is copied.  The user buffer must be 33 bytes or more in size.
  97. Calls to the .ATP Driver
  98. KillAllGetReq
  99. Parameter Block
  100.     --> 26    csCode    word    ; always KillAllGetReq (259)
  101.     --> 28    atpSocket    byte    ; socket on which to kill all pending
  102.               GetRequests
  103. KillAllGetReq aborts all outstanding GetRequest calls on the specified socket and completes them with reqAborted errors (it does not close the specified socket, it only kills all pending GetRequest calls on that socket).  To kill all the GetRequest calls, simply pass the desired socket number in the atpSocket field.
  104. Result codes    noErr        No Error                    (0)
  105.         cbNotFound    control block not found            (-1102)
  106. Setting the TRel Timer in SendRequest Calls
  107. It is now possible to set the TRel timer in SendRequest or NSendRequest calls with ATP XO (exactly once) service so as not to be locked into the pre-AppleTalk Phase 2 time of 30 seconds.  This is done by setting bit 2 in the atpFlags field to indicate to the driver that an extended parameter block is being used.  Make a standard SendRequest call, but add the timeout constant desired in the new TRelTime field byte of the parameter block.  Both nodes must be running AppleTalk Phase 2 for this feature to be supported.
  108. The timeout constants are enumerated as follows in the lower three bits of the TRelTime ($32 offset) byte:
  109.     000    $0    TRel timer set to 30 seconds
  110.     001    $1    TRel timer set to one minute
  111.     010    $2    TRel timer set to two minutes
  112.     011    $3    TRel timer set to four minutes
  113.     100    $4    TRel timer set to eight minutes
  114. All other values are reserved.
  115. Parameter Block
  116.     --> 50    TRelTime     byte    ; indicates time to wait for TRel packet
  117. Name Binding Protocol (NBP) Change:  Wildcard Lookup
  118. In AppleTalk Phase 2, NBP is enhanced to provide additional wildcard support.  The double tilde (≈), $C5, is now reserved in the object name and type strings and used in a lookup to mean a match of zero or more characters.  Thus “≈cliff” matches “cliff,” ”the cliff,” ”grazing off the cliff,” etc., and “123≈456” matches “123456,” “123zz456,” etc.  At most one ≈ is allowed in any string.  A single ≈ has the same meaning as a single =, which also must continue to be accepted.  The ≈ has no special meaning in zone names.  Clients of NBP must be aware that “old” (pre-AppleTalk Phase 2) nodes may not process this new wildcard feature correctly.  This feature should probably only be used when it is known that the responding devices are running Phase 2 drivers as well.
  119. Obtaining Zone Information Using the New .XPP Driver Calls
  120. Previously, Zone Information Protocol (ZIP) functions were accomplished via direct ATP calls to the local router.  It was rather nasty business, having to mess with the ATPUserData on subsequent calls to retain state information.  We now recommend the use of the following XPP driver calls to access ZIP.  Old ATP calls will continue to be supported for compatibility.  It should also be noted that with Phase 2 drivers present, the .XPP driver is automatically opened by MPP.
  121. GetZoneList
  122. Parameter Block
  123.     --> 26    csCode    word    ; always xCall (246)
  124.     --> 28    xppSubCode    word    ; always zipGetZoneList (6)
  125.     --> 30    xppTimeout    byte    ; retry interval (seconds)
  126.     --> 31    xppRetry    byte    ; retry count
  127.         32    <unused>    word    ; word space for rent.  see the super.
  128.     --> 34    zipBuffPtr    pointer    ; pointer to buffer (must be 578 bytes)
  129.     <-- 38    zipNumZones    word    ; no. of zone names in this response
  130.     <-- 40    zipLastFlag    byte    ; non-zero if no more zones
  131.         41    <unused>    byte    ; filler
  132.     --> 42    ziplnfoField    70 bytes    ; on initial call, set first word to zero 
  133. GetZoneList is used to obtain a complete list of zones on the internet.  ZipBuffPtr points to a buffer that.must be 578 bytes (ATPMaxData) in length.  The actual number of zone names returned in the buffer is returned in zipNumZones. The fields xppTimeout and xppRetry contain the ATP retry interval (in seconds) and count, respectively.
  134. The first time this call is made, the first word of the ziplnfoField should be set to zero.  When the call completes, zipLastFlag is non-zero if all the zone names fit into the buffer.  If not, the call should be made again immediately, without changing zipInfoField (it contains state information needed to get the next part of the list).  The call should be repeated until zipLastFlag is non-zero.  The 70-byte zipInfoField must always be allocated at the end of the parameter block.
  135. Result codes    noErr        No Error                    (0)
  136.         noBridgeErr    No router is available                (-93)
  137.         ReqFailed        SendRequest failed; retry count exceeded    (-1096)
  138. Following are short examples of using GetZoneList.
  139. Pascal
  140.  const
  141. { csCodes for new .XPP driver calls }
  142.   xCall = 246;
  143. { xppSubCodes }
  144.   zipGetLocalZones = 5;
  145.   zipGetZoneList = 6;
  146.   zipGetMyZone = 7;
  147.  type
  148. { offsets for xCall queue elements  }
  149.    xCallParam = packed record
  150.     qLink: QElemPtr;
  151.     qType: INTEGER;
  152.     ioTrap: INTEGER;
  153.     ioCmdAddr: Ptr;
  154.     ioCompletion: ProcPtr;
  155.     ioResult: OsErr;
  156.     ioNamePtr: StringPtr;
  157.     ioVRefNum: INTEGER;
  158.     ioRefNum: INTEGER;
  159.     csCode: INTEGER;
  160.     xppSubCode: INTEGER;
  161.     xppTimeOut: Byte;
  162.     xppRetry: Byte;
  163.     filler: INTEGER;
  164.     zipBuffPtr: Ptr;
  165.     zipNumZones: INTEGER;
  166.     zipLastFlag: INTEGER;
  167.     zipInfoField: packed array[1..70] of Byte;
  168.    end;
  169. procedure doGetZoneListPhs2;
  170. type
  171.    XCallParamPtr = ^XCallParam;
  172. var
  173.    xpb: XCallParamPtr;
  174.    resultCode: OSErr;
  175.    zoneBuffer, theBufferPtr: Ptr;
  176.    totalZones: integer;
  177. begin
  178.    xpb := XCallParamPtr(NewPtr(sizeof(XCallParam)));
  179.    zoneBuffer := NewPtr(33 * 100);    { size of maxstring * 100 zones }
  180.    theBufferPtr := NewPtr(578);    { size of atpMaxData }
  181.    xpb^.zipInfoField[1] := 0;    { ALWAYS 0 on first call.  contains state info                       on subsequent calls }
  182.    xpb^.zipInfoField[2] := 0;    { ALWAYS 0 on first call.  contains state info                       on subsequent calls }
  183.    xpb^.ioRefNum := XPPRefNum;        { driver refNum -41 }
  184.    xpb^.csCode := xCall;
  185.    xpb^.xppSubCode := zipGetZoneList;
  186.    xpb^.xppTimeOut := 3;
  187.    xpb^.xppRetry := 4;
  188.    xpb^.zipBuffPtr := Ptr(theBufferPtr);    { this buffer will be filled with }
  189.                         (  packed zone names }
  190. { initialization for loop }
  191.    xpb^.zipLastFlag := 0;
  192.    totalZones := 0;
  193.    resultCode := 0;
  194. { loop until zipLastFlag is non-zero or an error occurs }
  195.    while ((xpb^.zipLastFlag = 0) and (resultCode = 0)) do
  196.    begin
  197.    resultCode := PBControl(ParmBlkPtr(xpb), false);
  198.    if (resultCode = noErr) then
  199.      begin
  200.        totalZones := xpb^.zipNumZones + totalZones;
  201.        { you can now copy the zone names into the zoneBuffer }
  202.      end;
  203.    end;
  204.    DisposPtr(theBufferPtr);
  205.    DisposPtr(zoneBuffer);
  206.    DisposPtr(Ptr(xpb));
  207. end;
  208. C
  209. /* 
  210. csCodes for new .XPP driver calls
  211. */
  212. #define xCall            246
  213. /* 
  214. xppSubCodes 
  215. */
  216. #define zipGetLocalZones     5
  217. #define zipGetZoneList    6
  218. #define zipGetMyZone     7
  219. /*  
  220. offsets for xCall queue elements  
  221. */
  222. typedef struct
  223.     {
  224.     QElemPtr            qLink;
  225.     short            qType;
  226.     short            ioTrap;
  227.     Ptr            ioCmdAddr;
  228.     ProcPtr            ioCompletion;
  229.     OsErr            ioResult;
  230.     StringPtr            ioNamePtr;
  231.     short            ioVRefNum;
  232.     short            ioRefNum;
  233.     short            csCode;
  234.     short            xppSubCode;
  235.     unsigned char        xppTimeOut;
  236.     unsigned char        xppRetry;
  237.     short            filler;
  238.     Ptr            zipBuffPtr;
  239.     short            zipNumZones;
  240.     short            zipLastFlag;
  241.     unsigned char        zipInfoField[70];
  242. } xCallParam;
  243. doGetZoneListPhs2()
  244. {
  245.     xCallParam        xpb;
  246.     OSErr            resultCode = 0;
  247.     Ptr            zoneBuffer, theBufferPtr;
  248.     short            totalZones = 0;
  249.     zoneBuffer = NewPtr(33*100);        /* size of maxstring * 100 zones */
  250.     theBufferPtr = NewPtr(578);        /* size of atpMaxData */
  251.     xpb.zipInfoField[0] = 0;        /* ALWAYS 0 on first call.  contains                            state info on subsequent calls */
  252.     xpb.zipInfoField[1] = 0;        /* ALWAYS 0 on first call.  contains                            state info on subsequent calls */
  253.     /* initialization for loop */
  254.     xpb.zipLastFlag = 0;
  255.     xpb.ioCRefNum = XPPRefNum;        /* driver refNum -41 */
  256.     xpb.csCode = xCall;
  257.     xpb.xppSubCode = zipGetZoneList;
  258.     xpb.xppTimeOut = 3;
  259.     xpb.xppRetry = 4;
  260.     xpb.zipBuffPtr = (Ptr) theBufferPtr;    /* this buffer will be filled with
  261.                         the packed zone names */
  262.     /* loop until zipLastFlag is non-zero or an error occurs */
  263.     while(xpb.zipLastFlag == 0 && resultCode == 0) {
  264.         resultCode = PBControl(&xpb, false);
  265.         if(resultCode == noErr) {
  266.             totalZones += xpb.zipNumZones;
  267.             /* you can now copy the zone names into the zoneBuffer */
  268.         }
  269.     DisposPtr(theBufferPtr);
  270.     DisposPtr(zoneBuffer);
  271.     }
  272. }
  273. GetLocalZones
  274. Parameter Block
  275.     --> 26    csCode    word    ; always xCall (246)
  276.     --> 28    xppSubCode    word    ; always zipGetLocalZones (5)
  277.     --> 30    xppTimeout    byte    ; retry interval (seconds)
  278.     --> 31    xppRetry    byte    ; retry count
  279.         32    <unused>    word    ; filler
  280.     --> 34    zipBuffPtr    pointer    ; pointer to buffer (must be 578 bytes)
  281.     <-- 38    zipNumZones    word    ; no. of zone names in this response
  282.     <-- 40    zipLastFlag    byte    ; non-zero if no more zones
  283.         41    <unused>    byte    ; filler
  284.     --> 42    ziplnfoField    70 bytes    ; on initial call, set first word to zero
  285.             ; on subsequent calls, do not modify!
  286. This call has the same format and procedures as GetZoneList, the difference being that GetLocalZones returns a list of zone names currently defined only on the node’s network cable rather than the entire network.  The 70-byte zipInfoField must always be allocated at the end of the parameter block.
  287. Result codes    noErr        No Error                    (0)
  288.         noBridgeErr    No router is available                (-93)
  289.         ReqFailed        SendRequest failed; retry count exceeded    (-1096)
  290. Note:    The examples for GetZoneList will also work for GetLocalZones if you substitute the xppSubCode.
  291. GetMyZone
  292. Parameter Block
  293.     --> 26    csCode     word    ; always xCall (246)
  294.     --> 28    xppSubCode     word    ; always zipGetMyZone (7)
  295.     --> 34    zipBuffPtr     pointer    ; pointer to buffer (must be 33 bytes)
  296.     --> 42    ziplnfoField     70 bytes    ; first word must be set to zero on every call
  297. GetMyZone returns the node’s AppleTalk zone name.  This is the zone in which all of the node’s network visible entities are registered.  ZipBuffPtr points to a buffer that must be 33 bytes in length.  If noBridgeErr is returned by the call, there is no internet, and the zone name is effectively an asterisk (*).  The 70-byte zipInfoField must always be allocated at the end of the parameter block.
  298. Result codes    noErr        No Error                    (0)
  299.         noBridgeErr    No router is available                (-93)
  300.         ReqFailed        SendRequest failed; retry count exceeded    (-1096)
  301. Following are short examples of using GetMyZone.
  302. Pascal
  303. procedure getMyZonePhs2;
  304. var
  305.    xpb:xCallParam;
  306.    resultCode :OSErr;
  307.    myZoneNameBuffer:Ptr;
  308. begin
  309.    myZoneNameBuffer  := NewPtr(33);
  310.    xpb.ioCRefNum := xppRefNum;
  311.    xpb.csCode := xCall;
  312.    xpb.xppSubCode := zipGetMyZone;
  313.    xpb.zipBuffPtr := myZoneNameBuffer;
  314.    xpb.zipInfoField[1] := 0;        { ALWAYS 0 }
  315.    xpb.zipInfoField[2] := 0;        { ALWAYS 0 }
  316.    resultCode := PBControl(@xpb, false);
  317. end;
  318. C
  319. getMyZonePhs2()
  320. {
  321.     xCallParam    xpb;
  322.     OSErr        resultCode;
  323.     Ptr        myZoneNameBuffer;
  324.     myZoneNameBuffer  := NewPtr(33);
  325.     xpb.ioCRefNum = xppRefNum;
  326.     xpb.csCode = xCall;
  327.     xpb.xppSubCode = zipGetMyZone;
  328.     xpb.zipBuffPtr = (Ptr) myZoneNameBuffer;
  329.     xpb.zipInfoField[0] = 0;        /* ALWAYS 0 */
  330.     xpb.zipInfoField[1] = 0;        /* ALWAYS 0 */
  331.     resultCode = PBControl(&xpb, false);
  332. }
  333. Potential Nastiness
  334. When running on a node with Phase 2 compatible drivers, we always recommend using the .XPP calls outlined in the previous section.  Care was taken to keep backward compatibility with the already existing ATP ZIP calls (they are being trapped out with the Phase 2 drivers), but there are problems about which you should be aware.
  335. •    Do not rely on checking the TID (transaction ID validity bit) or other bits in the atpFlags, as some of you have been doing.  The atpFlags are not guaranteed to be correct on an ATP ZIP call with a Phase 2 driver present.
  336. •    Do not repeatedly stuff the router address back into the ATPParamBlock on subsequent ATP ZIP GetZoneList calls.  There exists the possibility of concurrent GetZoneList calls being made by other tasks and wrong router addresses being used (a small possibility yes, but it does exist).
  337. The AppleTalk Transition Queue
  338. To keep applications and other resident processes on the Macintosh informed of AppleTalk events, such as the opening and closing of AppleTalk drivers, a new transition queue has been implemented.  Processes can register themselves with the AppleTalk Transition Queue, and when a significant event occurs, they will be notified of this fact.  Each transition queue element has the following MPW assembly-language format:
  339. AeQentry    RECORD        0
  340. QLink        DS.L        1    ; link to next record
  341. QType        DS.W        1    ; unused
  342. CallAddr    DS.L        1    ; pointer to task record
  343.         ENDR
  344. Three calls have been provided in the LAP Manager to add an entry, remove an entry, and return a pointer to the AppleTalk event queue header.  The method for making calls to the LAP Manager is explained in the following section.  The queue is maintained by the LAP Manager, so it can be active even when AppleTalk (MPP) is not.
  345. Making a LAP Manager Call
  346. The LAP Manager is installed in the system heap at startup time, before the AppleTalk Manager opens the .MPP driver (hence, the inclusion of the AppleTalk Transition Queue in LAP Manager rather than under .MPP).  Calls are made to the LAP Manager by jumping through a low-memory location, with register D0 equal to a dispatch code that identifies the function.  The exact sequence is:
  347.               MOVEQ     #Code,D0        ; D0 = ID code of wanted LAP call
  348.               MOVE.L    LAPMgrPtr,An    ; An -> start of LAP manager (from $B18)
  349.               JSR       LAPMgrCall(An)  ; Call the LAP manager at entry point
  350. LAPMgrPtr     EQU       $B18            ; This points to our start (more
  351.                                         ; commonly known as ATalkHk2)
  352. LAPMgrCall    EQU       2               ; Offset to make LAP manager calls
  353. The AppleTalk Transition Queue LAP Calls
  354. LAddAEQ (D0=23)
  355. Call:        A0-->        Entry to be added to the AppleTalk event queue.
  356. The LAddAEQ call adds an entry, pointed to by A0, to the AppleTalk event queue.
  357.     MOVEQ    #LAddAEQ,D0    ; D0 = 23 code of LAddAEQ LAP call
  358.     MOVE.L    LAPMgrPtr,An    ; An -> start of LAP manager (from $B18)
  359.     JSR    LAPMgrCall(An)    ; Call the LAP manager at entry point
  360. LRmvAEQ (D0=24)
  361. Call:        A0-->        Entry to be removed from the AppleTalk event queue.
  362. The LRmvAEQ call removes an entry, pointed to by A0, from the AppleTalk event queue.
  363.     MOVEQ    #LRmvAEQ,D0    ; D0 = 24 code of LRmvAEQ LAP call
  364.     MOVE.L    LAPMgrPtr,An    ; An -> start of LAP manager (from $B18)
  365.     JSR    LAPMgrCall(An)    ; Call the LAP manager at entry point
  366. LGetAEQ (D0=25)
  367. Return:    A1-->        Pointer to the AppleTalk event queue header.
  368. The LGetAEQ call returns a pointer in A1 to the AppleTalk event queue header, previously described.
  369.     MOVEQ    #LGetAEQ,D0    ; D0 = 25 code of LGetAEQ LAP call
  370.     MOVE.L    LAPMgrPtr,An    ; An -> start of LAP manager (from $B18)
  371.     JSR    LAPMgrCall(An)    ; Call the LAP manager at entry point
  372. The Transitions
  373. Each process is called at CallAddr when any significant transitions occur.  A value is passed in, which indicates the nature of the event.  Additional parameters may also be passed and a pointer to the task’s queue element is also passed.  This is provided so processes may append their own data structures (e.g., a globals pointer) at the end of the task record, which can be referenced when they are called.  Processes should follow the MPW C register conventions.  Registers D0, D1, D2, A0, and A1 are scratch registers that are not preserved by C functions.  The arguments passed to the process should be left on the stack, since the calling routine removes them.  All other registers should be preserved.
  374. The Open Transition
  375. For AppleTalk open transitions, the process has the following interface:
  376. From assembly language, the stack upon calling looks as follows:
  377. OpenEvent    RECORD        0
  378. ReturnAddr    DS.L        1    ; address of caller    
  379. theEvent    DS.L        1    ; = 0 ; ID of Open transaction
  380. aqe        DS.L        1    ; pointer to task record
  381. SlotDevParam    DS.L        1    ; pointer to Open parameter block
  382.         ENDR
  383. This routine is called only when the open routine for .MPP executes successfully.  Every entry in the transition queue is called in the same order that the entries were added to the queue.  If AppleTalk is already open and an _Open call is made, no process is called.  The process should return a function result in D0, which is currently ignored.
  384. A pointer to the open request parameter block is passed to the open event process for information only (i.e., the event process may not prevent AppleTalk open calls).  Those fields which are of interest are OpenPB->ioPermssn, passed by the caller, and OpenPB->ioMix, which is both passed by the caller and updated by the .MPP open (see Inside Macintosh, Volume V, The AppleTalk Manager).
  385. The Close Transition
  386. For AppleTalk close transitions, the process has the following interface:
  387. From assembly language, the stack upon calling looks as follows:
  388. CloseEvent    RECORD        0
  389. ReturnAddr    DS.L        1    ; address of caller    
  390. theEvent    DS.L        1    ; = 2 ; ID of Close transaction
  391. aqe        DS.L        1    ; pointer to task record
  392.         ENDR
  393. The process is being told that AppleTalk is closing, which gives the process an opportunity to close gracefully.  Every entry in the event queue is called, one after the other, in the same order that the entries were added to the queue.  The close action cannot be cancelled.  The process should return a function result in D0, which is currently ignored.
  394. The ClosePrep and CancelClosePrep Transitions
  395. The AtalkClosePrep and the CancelAtalkClosePrep control calls are used by various elements of the System, such as the Chooser, to inform or query AppleTalk clients of the closing of network drivers.  For example, on a machine equipped to go to sleep or to wake up, the _Sleep trap is used by such entities as sleeptimer, Finder, and Shutdown to inform AppleTalk clients that  it is desirable for the the network driver (.MPP) to be closed.  The _Sleep trap may be trying to do any of the following three things: request permission for sleep, alert for impending sleep, or inform that wake up is underway.  The sleep request calls the following two .MPP control calls; these calls are made before sleep queue procedures are called.
  396. The first control call, AtalkClosePrep, is used to inform or query AppleTalk clients that the network driver might be closed in the very near future.  The call has the following interface:
  397. AtalkClosePrep (csCode = 259)
  398. Parameter Block
  399.         --> 26    csCode    word    ;always AtalkClosePrep
  400.         <-- 28    clientName    pointer    ;-> name of client using driver
  401. Result codes    noErr        The AppleTalk network driver (.MPP) may be closed
  402.         closeErr        The AppleTalk network driver (.MPP) may not be closed
  403. clientName is a pointer to an identifying string that is returned only if the result is closeErr.  Note that the pointer may be NIL in this case, while the pointer is always NIL if the return code is noErr.
  404. All tasks in the AppleTalk Transition Queue are called with the event ClosePrep.  The tasks can prevent driver closure with a negative response to the event call.  Each task is called with the following interface:
  405. From assembly language, the stack upon calling looks as follows:
  406. ClosePrep        RECORD        0    ;top of the stack
  407. ReturnAddr        DS.L        1    ;addr of caller
  408. theEvent        DS.L        1    ;=3
  409. aqe            DS.L        1    ;->task rec.
  410. clientName        DS.L        1    ;ptr. to ptr. to name of client
  411.             ENDR
  412. For this event, theEvent = 3, and the task is being both informed and asked if closing the network driver is acceptable.  If driver closure is acceptable, the task need only to reply affirmative (D0 = 0), or if not acceptable, deny the request (D0 ≠ 0).  The task may use the event as an opportunity to “prepare to die” or may simply respond.  For example, a task may prevent further sessions from forming while waiting for the actual close event.
  413. clientName is a pointer to a field in the .MPP control call parameter block where the task may optionally store a string address.  This string identifies the client who has AppleTalk in use and is denying the request to close it.  This string may be used in a dialog to inform the user to take appropriate action or explain why the requested action could not be performed.
  414. If any task responds negatively, no subsequent tasks are called.  Any tasks called prior to the one that denied a query are recalled with another event, CancelClosePrep (described below), enabling them to “undo preparations to die,” and the control call then completes with a closeErr error.
  415. From assembly language, the stack upon calling looks as follows:
  416. CancelClosePrep    RECORD        0    ;top of the stack
  417. ReturnAddr        DS.L        1    ;addr of caller
  418. theEvent        DS.L        1    ;=4
  419. aqe            DS.L        1    ;->task rec.
  420.             ENDR
  421. For this event, theEvent = 4, and the task is being informed that although it has recently approved a request to close the network driver, a subsequent task in the AppleTalk Transition Queue has denied permission.  This event permits the task to undo any processing that may have been performed in anticipation of the network driver being closed.  The process should return a function result in D0, which is currently ignored.
  422. The second new control call, CancelAtalkClosePrep, is used to undo the effects of a successful AtalkClosePrep control call.  Even though all queried tasks in the AppleTalk Transition Queue approved of network driver closure, other conditions may exist after making the AtalkClosePrep control call which prohibit network driver closure.  In this case, it is necessary to recall all tasks to undo any processing that may have been performed in anticipation of the network driver being closed.  The control call to do this has the following interface:
  423. CancelAtalkClosePrep (csCode = 260)
  424. Parameter Block
  425.     --> 26    csCode    word    ;always CancelAtalkClosePrep
  426. Result codes    noErr        Nothing could possibly go wrong
  427. All tasks in the AppleTalk Transition Queue are called with the event CancelClosePrep as described above.
  428. Note:    The use of the low-memory global ChooserBits ($946) is no longer an acceptable means of preventing AppleTalk from closing when AppleTalk Phase 2 is present.  Transitions other than defined above must be ignored and are reserved for future implementation.  In the future transitions may be defined for notifying processes when a change in zone name occurs.
  429. Potential Compatibility Problems
  430. Using DDP and Talking to Routers
  431. If, for some reason, you need to talk to any router via DDP, always use the GetAppleTalkInfo call outlined in this Note to get the router’s actual 24-bit address.
  432. The WriteLAP function (csCode = 243) to the .MPP driver is no longer supported, since a node is no longer identified only by its eight-bit (LAP) node ID.
  433. On a Macintosh running the AppleTalk Internet Router software, the SelfSend flag is always set, so if you try to clear this flag using the PSetSelfSend call (Inside Macintosh, Volume V-514), you will get an error.
  434. Further Reference:
  435. •    Inside AppleTalk
  436. •    Inside Macintosh, Volume II, The AppleTalk Manager
  437. •    Inside Macintosh, Volume V, The AppleTalk Manager
  438. •    EtherTalk and Alternate AppleTalk Connections Reference, May 5, 1989—Draft  (DTS)
  439. •    AppleTalk Phase 2 Protocol Specification (DTS)
  440. •    Macintosh Portable Developer Notes (DTS)
  441. NW 4 - ASP and AFP Description Discrepancies
  442. Networking    
  443. Written by:    Mark Bennet    August 1988
  444. The descriptions of the AppleTalk Session Protocol and AppleTalk Filing Protocol functions within the body of the AppleTalk Manager chapter are incorrect and conflict with those in the Summary of the AppleTalk Manager. This technical note resolves the discrepancy.
  445. The descriptions of the AppleTalk Session Protocol and AppleTalk Filing Protocol functions which are described on pages 534 through 548 of Inside Macintosh Volume V conflict with the descriptions in the Summary of the AppleTalk Manager section, pages 554 through 559. The descriptions in the Summary of the AppleTalk Manager section are correct and should be followed.
  446. The Summary of the AppleTalk Manager does not, however, present a description of the correct meaning of the arrows next to the parameter names in the function descriptions. The meaning of the arrows is equivalent to the one given to them in the descriptions of other Operating System calls, i.e.:
  447.     Arrow            Meaning
  448.     Æ                Parameter is passed
  449.     ¨                Parameter is returned
  450.     ´                Parameter is passed and returned
  451. Further Reference:
  452. •    The AppleTalk Manager
  453. NW 5 - High-Level AppleTalk Routines
  454. Networking    
  455. Revised by:        March 1988
  456. Written by:    Fred A. Huxham    May 1987
  457. What you need to do in order to use high-level AppleTalk routines depends upon the interfaces you are using. Some differences are outlined below.
  458. MPW before 2.0
  459. When calling the old high-level AppleTalk routines, many programmers get mysterious “resource not found” errors (-192) from such seemingly harmless routines as MPPOpen. The resource that is not being found is ‘atpl’, a resource that contains all the glue code to the high-level routines. In order to use the high-level routines, your application must have this resource in its resource fork. The ‘atpl’ resource is included in a file called “AppleTalk” with any compilers that use this outdated version of the AppleTalk interface.
  460. MPW 2.0 and newer
  461. A newer version of the alternate interfaces is available in MPW 2.0; it includes bug fixes and increased Macintosh II compatibility. With this version of the interface, the ‘atpl’ resource is no longer used. Glue code is now linked into your application.
  462. This will be the final release of the current-style interface. It will be supported for some time as the alternate interface. We have moved to a more straightforward and simple preferred interface, which is also implemented in MPW 2.0 and newer, and is described in the AppleTalk Manager chapter of Inside Macintosh vol. V. Developers are free to continue to use the alternate interface, but in the long run it will be advantageous to move to the preferred interface.
  463. Third Party Compilers
  464. Third party compilers use interfaces that are built from Apple’s MPW interfaces. Some compilers may not have upgraded to the new interfaces yet. Contact the individual compiler manufacturers for more information.
  465. Further Reference:
  466. •    The AppleTalk Manager
  467. •    Inside AppleTalk
  468. •    AppleTalk Manager Update
  469. NW 6 - KillNBP Clarification
  470. Networking    
  471. Written by:    Mark Bennett    August, 1988
  472. This technical note clears up some confusion regarding the Name Binding Protocol KillNBP function.
  473. The description of the PKillNBP function on page 519 of Inside Macintosh Volume V is somewhat confusing. The data type of the parameter thePBptr is incorrectly given as ATPPBPtr and the pointer to the queue element from the NBP call to be aborted is incorrectly given as being passed in aKillQEl. The following is a correct description of the KillNBP function:
  474. KillNBP function
  475. FUNCTION PKillNBP (thePBptr: MPPPBPtr; async: BOOLEAN) : OSErr;
  476.     Parameter block
  477.         Æ    26    csCode    word    Always PKillNBP
  478.         Æ    28    nKillQEl    pointer    Pointer to queue element
  479. Further Reference:
  480. •    The AppleTalk Manager
  481. NW 7 - Avoid Use of Network Events
  482. Networking    
  483. Revised by:        March 1988
  484. Written by:    Bryan Stearns    July 1987
  485. Future System software enhancements will not support network events. This note gives hints on weaning your application from the use of network events.
  486. What are network events?
  487. When the Event Manager was designed, an event number was reserved for future support of “network events”. Later, when the AppleTalk Pascal Interfaces were written, a completion routine was created that, when an asynchronous AppleTalk operation finished, would post an event using networkEvt in the evtNum field.
  488. Only the AppleTalk Pascal Interfaces generate network events. Assembly-language users of the AppleTalk drivers (and those who called the AppleTalk drivers directly from high-level languages, using PBControl calls) either provide a completion routine of their own, or poll the ioResult field of the parameter block passed with the call (when ioResult became negative or zero, the call is complete).
  489. Why not use network events?
  490. In some cases, network events can be lost. If the Event Manager finds that the queue is full while posting an event, it discards the oldest event. In a situation (such as a server) where multiple asynchronous ATP requests may complete at once, there is a chance that events may be dropped off the end of the queue. This is more likely if the same machine is also handling user-interface events (like keypresses and mouse actions).
  491. Also, in developing improvements to our operating system, it has become apparent that to continue support of network events, we would have to compromise future enhancements to our system. So, future versions of the Macintosh operating system may ignore network events instead of passing them to the application.
  492. How can I tell that my calls have completed without using network events?
  493. As described on page II-275 of Inside Macintosh, you can poll the abResult field of the call’s ABusRecord; when this value becomes negative or zero, the call has completed. You can do this in your main event loop.
  494. With this technique, you can ignore any network events returned by GetNextEvent, since the AppleTalk Pascal Interfaces will be posting events anyway. If your application starts enough asynchronous operations, it’s possible that their network events will cause other non-network events to be lost. To prevent this, you should call FlushEvents(networkMask,0) frequently to purge any accumulated network events from the event queue.
  495. You may also consider using the new preferred high-level interface calls; see M.NW.AppleTalk for more information.
  496. Further Reference:
  497. •    AppleTalk Manager
  498. •    M.NW.AppleTalk 
  499. NW 8 - Opening AppleTalk
  500. Networking    
  501. Written by:    Mark Bennett    February 1989
  502. This Technical Note describes the most effective, safe, and compatible way to open the AppleTalk drivers, .MPP and .ATP.
  503. The process of opening the AppleTalk drivers, .MPP and .ATP, can be greatly simplified.  The AppleTalk Manager chapters of Inside Macintosh describe the calls MPPOpen and ATPLoad for use by high-level languages.  They also describe the process of examining low-memory globals SPConfig and PortBUse before calling _Open for assembly language use of AppleTalk.
  504. Starting with the 128K ROM, the .MPP driver already has all the code built in for checking the low-memory globals SPConfig and PortBUse before trying to complete the _Open call.  Furthermore, the .MPP driver will automatically open the .ATP driver as part of its opening process.  Therefore, since all of the required checks are made inside the driver itself, we recommend that a simple _Open call be made to the .MPP driver when you need to use AppleTalk.  In a high-level language like Pascal, this call would look like the following:
  505.     result := OpenDriver('.MPP', refnum);
  506. In C:
  507.     result = OpenDriver("\p.MPP", &refnum);
  508. And in assembly language:
  509. openAT    SUB.W    #ioQElSize,SP    ; Make space for paramblock on stack 
  510.             ; since _Open is always synchronous.            ;  Using .W is slightly more efficient 
  511.             ; and is safe since ioQElSize is small.
  512.     MOVE.L    SP,A0    ; Point A0 to paramblock.
  513.     LEA    mppName,A1    ; Point A1 to driver name.
  514.     MOVE.L    A1,ioFileName(A0); Put pointer to name in paramblock.
  515.     CLR.B    ioPermssn(A0)    ; Clear so won't look like OpenDeskAcc.
  516. _Open
  517.     MOVE.W    ioRefNum(A0),D1    ;You might want this later. Who knows?
  518.     ADD.W    #ioQElSize,SP    ; Reclaim space on stack.
  519.     RTS        ; D0 contains result code.
  520. mppName    DC.B    4
  521.     DC.B    '.MPP'
  522. By using just the simple _Open call to the .MPP driver, you can ensure that your code will be compatible with future versions of AppleTalk that might not make use of low-memory globals.
  523. Further Reference:
  524. •    Inside Macintosh, Volumes II-261, IV-229, & V-507, The AppleTalk Manager
  525. NW 9 - RegisterName
  526. Networking    
  527. Written by:    Mark Bennett    February 1989
  528. The verify flag indicator byte (verifyFlag) of the AppleTalk RegisterName function should always be set TRUE in published code.
  529. The AppleTalk chapter of Inside Macintosh, Volume II-322, in describing the RegisterName function, states:
  530. “If verifyFlag is TRUE, RegisterName checks on the network to see if the name is already in use, and returns a result code of nbpDuplicate if so.”
  531. Note that verifyFlag should always be TRUE in published code.  The design of the Name Binding Protocol (NBP) requires that an entity name be unique.  The way RegisterName ensures this uniqueness is by broadcasting a lookup request for the registered name.  If any entity responds, then RegisterName knows that the name would not be unique and returns an error.  Some developers, in anticipating the time delay involved in broadcasting a lookup request and waiting for a response, have opted to set verifyFlag to FALSE, not realizing the potential danger in doing so.
  532. Apple provides verifyFlag for experimental or developmental purposes, such as narrowing down a problem in registering a name on a network.  Always make sure that code which ships has verifyFlag set to TRUE.
  533. Further Reference:
  534. •    Inside Macintosh, Volume II-261, The AppleTalk Manager
  535. NW 10 - AppleShare Foreground Applications
  536. Networking    M.NW.AppleShareApp
  537. Revised by:    Jim Luther    July 1992
  538. Written by:    Fred A. Huxham    November 1987–March 1988
  539. This Technical Note outlines the requirements and restrictions of an AppleShare foreground application (AppleShare foreground applications are called concurrent server applications in the AppleShare File Server Administrator’s Guide). This information pertains only to AppleShare system software versions 1.1 through 2.0. AppleShare version 3.0 and Macintosh file sharing run under Macintosh System 7. AppleShare foreground applications are not necessary and are not supported by AppleShare version 3.0 or Macintosh file sharing.
  540. Changes since March 1988:  Added note that AppleShare version 3.0 and Macintosh file sharing don’t support AppleShare foreground applications. Added additional notes about AppleShare foreground applications.
  541. An AppleShare server requires a dedicated Macintosh. The server, however, is implemented as an interrupt-driven application that runs in the system heap of the server machine. This allows the running of a concurrent or foreground application that will live in the application heap of the server machine. An example of a foreground application is LaserShare, the LaserWriter spooler available from Apple.
  542. An AppleShare foreground application has a few additional restrictions and requirements beyond that of a normal Macintosh application:
  543. 1. In order for AppleShare to recognize your program as a foreground application, it must contain a resource of type 'fgnd', ID=1, containing a longword of $00000000.
  544. 2. Do not make any file system calls outside of server volumes’ Server Folders. If a foreground application needs to create files, it is recommended that the application create a folder inside the Server Folder and then create all its files within that folder. For example, all print spooler or E-mail files must reside within the Server Folder, and preferably, within a folder that is inside the Server Folder. To find the Server Folder,
  545. •    Make a PBHGetVlnfo call on the volume.
  546. •    Examine ioVFndrInfo[8] (long integer).
  547. •    If ioVFndrInfo[8] is nonzero, it is the directory ID of the Server Folder.
  548. 3. Do not make file system calls or in any way modify the AppleShare server application, the Parallel Directory Structure, or the user or group databases within the Server Folder of any volume. Also, do not rely on the presence or formats of these structures, as they are subject to change!
  549. 4. Do not eject or unmount a volume that is not in drive 1 or 2.
  550. 5. Do not call the Shutdown trap; instead, quit by calling ExitToShell or by dropping out of the main event loop.
  551. In addition to these restrictions, here are a few other things that are good to know when writing an AppleShare foreground application.
  552. Multiple AppleShare Foreground Application Support
  553. Although you can install multiple AppleShare foreground applications on an AppleShare server, only one can be active at a time. Since the AppleShare Admin application is an AppleShare foreground application, users will have to quit Admin to run your application and quit your application to run Admin.
  554. Number of Open Files Allowed
  555. Any files opened by an AppleShare foreground application count toward the maximum number of open files allowed on the AppleShare file server. See Macintosh Technical Note #216, “AppleShare and File-Sharing Limits,” for the number of open files allowed on a particular AppleShare file server.
  556. How Much Memory Does an AppleShare Foregound Application Get?
  557. Foreground applications are launched by an AppleShare file server, so AppleShare decides how big your application heap will be. First AppleShare reads your 'SIZE' resource. It uses ID 0 (the Finder-created 'SIZE' resource) if it is available. It uses ID -1 (the default 'SIZE' resource created by the programmer) if ID 0 isn’t available. It uses any other 'SIZE' resource it can find if IDs 0 and-1 aren’t there. If no 'SIZE' resources are found, then AppleShare uses 196 KB for the size and the minimum size. If your application has a 'SIZE' less than 128 KB, then 128 KB is used for the size and the minimum size.
  558. AppleShare then attempts to allocate the minimum size for your application (as found above). If successful, AppleShare sets the system cache to 32 KB (the minimum). (At this point, your application could still be launched if any of the following things fail.)  Then, AppleShare attempts to allocate the default size for your application (as found above). After that, AppleShare gives any remaining memory back to the system cache.
  559. Further Reference:
  560. •    AppleShare File Server Administrator’s Guide
  561. •    Macintosh Technical Note #216, AppleShare and File-Sharing Limits
  562. NW 11 - AppleShare and File-Sharing Limits
  563. Networking    M.NW.AppleShareLimits
  564. Revised by:    Jim Luther    July 1992
  565. Written by:    Mark Bennett    October 1988
  566. This Technical Note describes some machine-dependent limits of current versions of AppleShare file servers (including Macintosh file sharing).
  567. Changes since October 1988: Added information for AppleShare system software version 3.0 and Macintosh file sharing.
  568. The following chart lists some current AppleShare limits that are based upon the chosen server platform and memory configuration. The limits that otherwise might be present on a workstation are still in effect and are not affected by the workstation being logged on to an AppleShare server. These limits will change in the future.
  569. AppleShare 1.1 and 2.0 Limits
  570.     Server:    Server:
  571.     Macintosh Plus, SE,    Macintosh II With
  572. Description of Limit    or II With 1 MB    More Than 1 MB
  573. Number of Users    25    50
  574. Number of Locked Ranges    1000    2000
  575. Number of Open Files    80    160
  576. Number of Volumes    16    16
  577. AppleShare 3.0 and Macintosh File-Sharing Limits
  578.     File Server:    File Server:
  579. Description of Limit    Macintosh File Sharing    AppleShare 3.0
  580. Number of Users    10    120*
  581. Number of Locked Ranges    200    2400*
  582. Number of Open Files    346*    346**
  583. Number of Share Points    10    50
  584. *    The maximum number of users supported by AppleShare version 3.0 can be adjusted with the AppleShare Admin application or with the SCSetSetupInfo AppleShare Server Control call. AppleShare version 3.0 allocates 20 locked ranges per user.
  585. **    This is the maximum number of file control blocks (FCBs) allowed by the Macintosh File Manager. The system and any applications running on the server Macintosh (including the file server) will use some of those available FCBs.
  586. Further Reference:
  587. •    AppleShare File Server Administrator’s Guide
  588. •    Macintosh Technical Note #167, AppleShare Foreground Applications
  589. NW 12 - AppleShare-able Applications and the Resource Manager
  590. Networking    
  591. Revised by:        March 1988
  592. Written by:    Bryan Stearns    March 1987
  593. Normally, applications on an AppleShare server volume cannot be executed by more than one user at a time. This technical note explains why, and tells how you can enable your application to be shared.
  594. The Resource Manager versus Shared Files
  595. Part of the explanation of why applications are not automatically sharable is based on the design of the Resource Manager.  The Resource Manager is a great little database. It was originally conceived as a way to keep applications localizable (a task it has performed admirably), and was found to be an excellent foundation for the Segment Loader, Font Manager, and a large part of the rest of the Macintosh operating system.
  596. However, it was never designed to be a multi-user database. When the Resource Manager opens a resource file (such as an application), it reads the file’s resource map into memory. This map remains in memory until the resource file is closed by the Segment Loader, which regains control when the application exits. Sometimes it is necessary to write the map out to disk; normally, this is only done by UpdateResFile and CloseResFile.
  597. If two users opened the same resource file at the same time, and one of them had write access to the file and added a resource to it, the other user’s Resource Manager wouldn’t know about it; this would make the other user’s copy of the file’s original resource map invalid. This could cause (at least) a crash; if both users had write access, it’s not unlikely that the resource file involved would become corrupted. Also, although you can tell the Resource Manager to write out an updated resource map, there’s no way for another user to tell it to refresh the copy of the map in memory if the file changes.
  598. What does all this have to do with running my application twice?
  599. Your application is stored as a resource file; code segments, alert and dialog templates, etc., are resources. If you write to your application’s resource file (for instance, to add configuration information, like print records), your application can’t be shared.
  600. In Apple’s compatibility testing of existing applications (during development of AppleShare), we found quite a few applications, some of them quite popular, that wrote to their own resource files. So we decided, to improve the safety of using AppleShare, to always launch applications using a combination of access privileges such that only one user at a time could use a given application (these privileges will be discussed in a future Technical Note). In fact, AppleShare opens all resource files this way, unless the resource file is opened with OpenRFPerm and read-only permission is specified.
  601. But my application doesn’t write to itself!
  602. We realize that many applications do not. However, there are other considerations (covered in detail, with suggestions for fixes, in “Application Development in a Shared Environment”, available from APDA ). In brief, here are the big ones we know about:
  603. •    Does your application create temporary files with fixed names in a fixed place (such as the  directory containing the application)? Without AppleShare’s protection, two applications  to use the same temporary file could be disastrous.
  604. •    Is your application at least “conscious” of the fact that it may be in a multi-user environment? For instance, does it work correctly if a volume containing an existing document is on a locked volume? Does it check all result codes returned from File Manager  calls, and ResError after relevant Resource Manager calls?
  605. OK, I follow the rules. What do I do to make my application sharable?
  606. There is a flag in each file’s Finder information (stored in the file’s directory entry) known as the “shared” bit. If you set this bit on your application’s resource file, the Finder will launch your application using read-only permissions; if anyone else launches your application, they’ll also get it read-only (their Finder will see the same “shared” bit set.).
  607. Three important warnings accompany this information:
  608. •    The definition of the “shared” bit was incorrect in previous releases of information and software from Apple. This includes the June 16, 1986 version of M.TB.Finder Flags (fixed in the March 2, 1987 version), as well as all versions of ResEdit before and including 1.1b3 (included with MPW 2.0). For now, the most reliable way to set this bit is to get the 1.1b3 version of ResEdit, use it to Get Info on your application, and check the  box labeled “cached” (the incorrect documentation upon which ResEdit et al.] was based  called the real shared bit “cached”; the bit labeled as “shared” is the real cached bit [a  currently unused but reserved bit which should be left clear]).
  609. •    By checking this bit, you’re promising (to your users) that your application will work entirely correctly if launched by more than one user. This means that you follow the other rules, in addition to simply not writing to your application’s own resource file. See  “Application Development for a Shared Environment,” and test carefully!
  610. •    Setting this bit has nothing to do with allowing your application’s documents to be shared;  you must design this feature into your application (it’s not something that Apple system  software can take care of behind your application’s back.). You should realize from reading  this note, however, that if you store your document’s data in resource files, you won’t be  able to allow multiple users to access them simultaneously.
  611. Further Reference:
  612. •    The Resource Manager
  613. •    “Application Development in a Shared Environment”
  614. •    M.TB.Finder Flags
  615. NW 13 - AppleTalk: The Rest of the Story
  616. Networking    
  617. Updated by:    Rich Kubota and Jim Luther    January 1993
  618. Written by:    Rich Kubota and Scott Kuechle    February 1992
  619. This Technical Note discusses the updates and modifications to a number of facets of the lower levels of AppleTalk Phase 2 since the release of Inside Macintosh Volume VI. Topics range from discussion of the new Datagram Delivery Protocol (DDP) layer calls to the AppleTalk Multiple Node Architecture to a discussion at the driver level of the new Multivendor ADEV Architecture. Most of the information presented here concerns AppleTalk versions 56 through 58; however, additional material is presented to clarify and correct material presented in other AppleTalk documentation relating to all versions of AppleTalk.
  620. Reordered subjects according to the order of the AppleTalk version in which the feature was first implemented. Added a table of contents to make it easier to find material. Added a discussion on Multivendor ADEV Architecture, the .TOKN driver interface, plus information on making AppleTalk drivers compatible with virtual memory under system software version 7.0.x. Added a description of the change to the .ENET interface presented by the Apple SONIC-based Ethernet drivers. Added socket listener sample code. Added AppleTalk version list.
  621. Changes since September 1992: Corrected the .TOKN interface to remove reference to the A1 register on packet reception. Described a bug with the LAPAddATQ and LAPRmvATQ glue code that exists in the MPW Interface.o library file, and published an Assembler glue code file to work around the problem. Described a change to the .ENET EGetInfo call interface. Described a change to the 'atlk' AGetInfo call required of ADEVs to support SNMP (Simple Network Management Protocol). Discussed other changes required for .TOKN and .ENET support of SNMP. Provided additional clarification to the LAP Manager calls, LRdDispatch and LWrtInsert. Presented a correction to the ENET.h header file supplied with MPW 3.2.x.
  622. Introduction        2
  623.     Where Can I Get the Latest Version of AppleTalk?    3
  624. The 'atkv' Gestalt Selector    4
  625. Sample Socket Listener    4
  626.     Socket Listener Review    5
  627.     Timing Considerations for LocalTalk    5
  628.     Register Usage    5
  629.     Socket Listener Overview    6
  630.     Socket Listener Assembler Code    7
  631.     Initializing the Socket Listener    12
  632.     Using the Socket Listener    14
  633. The AppleTalk Transition Queue    15
  634.     Bug with LAPAddATQ and LAPRmvATQ Glue Code    16
  635.     Calling the AppleTalk Transition Queue    18
  636.     Standard AppleTalk Transition Constants    18
  637.     The Flagship Naming Service    19
  638.         The ATTransNameChangeAskTask Transition    19
  639.         The ATTransNameChangeTellTask Transition    20
  640.         The ATTransCancelNameChange Transition    20
  641.         System 7.0 Sharing Setup cdev / Flagship Naming Service Interaction    21
  642.     AppleTalk Remote Access Network Transition Event    21
  643.         The ATTransNetworkTransition Transition    21
  644.         Network Transition Event for AppleTalk Remote Access    21
  645.     Cable Range Change Transition Event    22
  646.         The ATTransCableChange Transition    23
  647.     The Speed Change Transition Event    23
  648.         The ATTransSpeedChange Transition    24
  649.     Sample Pascal Source to LAPMgrExists Function    24
  650.     Sample AppleTalk Transition Queue Function    25
  651.         Sample AppleTalk Transition Queue Function in C    25
  652.         Sample AppleTalk Transition Queue Function in Pascal    29
  653. Multivendor ADEV Architecture    36
  654.     Original Limitations    36
  655.     .TOKN Driver Shell    37
  656.     .TOKN Driver Basics    37
  657. Driver Considerations for Virtual Memory    38
  658.     Limiting DeferUserFn Calls    39
  659.     Implementing DeferUserFn    40
  660. SONIC-Based Ethernet Driver Software Interface Change    40
  661.     EGetInfo Changes    40
  662.     Distinguishing Apple’s SONIC-Based Ethernet Systems    41
  663. Correction to the ENET.h Header File    42
  664. AppleTalk Multiple Node Architecture    42
  665.     What Is It?    43
  666.     Glue Code For Multinode Control Calls    43
  667.     Things You Need to Know When Writing a Multinode Application    45
  668.         AddNode (csCode=262)    46
  669.         RemoveNode (csCode=263)    47
  670.         Receiving Packets    47
  671.     Sending Datagrams Through Multinodes    48
  672.         NetWrite (csCode=261)    48
  673.     AppleTalk Remote Access Network Number Remapping    49
  674.     Is There a Router on the Network?    49
  675. New for AppleTalk ADEVs    49
  676.     AGetInfo (D0=3)    50
  677.     AAddNode (D0=9)    51
  678.     ADelNode  (D0=10)    52
  679.     AGetNodeRef  (D0=11)    53
  680.     AOpen  (D0=7)    53
  681.     AClose (D0=8)    54
  682.     AInstall (D0=1)    54
  683.     AShutDown (D0=2)    54
  684.     Receiving Packets    54
  685.     Defending Multinode Addresses    55
  686. Corrections/Clarifications to the LAP Manager    55
  687.     LRdDispatch (DO = 1)    55
  688.     LWrtInsert (DO = 2)    55
  689. AppleTalk Version Information    56
  690. Contacting Apple Software Licensing    57
  691. Introduction
  692. This Tech Note differs from previous revisions in that the subjects have been reordered. The topics are presented according to the order of the AppleTalk version in which the feature was first implemented. You can find new topics and modifications to this Tech Note by looking for material set off by change bars in the margins.
  693. The first section in this Note, “The 'atkv' Gestalt Selector,” discusses the new Gestalt selector 'atkv', which provides version information when AppleTalk is available. 
  694. The next section, “Sample Socket Listener,” presents a sample socket listener, including initialization code to assist high-level language programmers. There socket listener comments describe in detail the basic functions of packet handling at the data link layer.
  695. The next section, “The AppleTalk Transition Queue,” discusses the AppleTalk Transition Queue including its support for the Flagship Naming Service, AppleTalk Remote Access, and changes to processor speed that can affect LocalTalk and other processes dependent on processor speed. Included is Pascal source code for checking whether the Phase 2 LAP Manager exists to support the Transition Queue mechanism, plus sample Transition Queue handlers written in both C and Pascal. This section includes a description of an important bug that exists in the glue code, implemented for the LAPAddATQ and the LAPRmvATQ functions. The glue code is from the MPW Interface.o file. Replacement glue routines are provided to work around the problem for both MPW and Think programmers.
  696. The section “Multivendor ADEV Architecture” presents the Multivendor ADEV Architecture, which allows for Ethernet and token ring cards from multiple vendors to be installed on the same system. Included is a description of the functionality of the new driver shells for Ethernet and token ring, plus a description of the .TOKN interface required for compatibility with the new ADEV Architecture.
  697. The section “Driver Considerations for Virtual Memory” shows how to modify driver code for compatibility with system software version 7.0 virtual memory.
  698. SONIC-Based Ethernet Driver Software Interface Change
  699. The section “SONIC-Based Ethernet Driver Software Interface Change” presents a change to the .ENET interface that resulted from the implementation of the SONIC Network Interface Controller on the Ethernet NB Card and in the Macintosh Quadra computer’s built-in Ethernet. The change concerns the EGetInfo function, which now returns additional network information for Apple Ethernet products based on the SONIC chip.
  700. The section “Correction to the ENET.h Header File” presents a correction to the header file for programs that will make a parameter block Control call to the .ENET, .TOKN, or .FDDI driver, to add or delete multicast addresses. This problem applies only to C programs that are written to include the ENET.h file supplied with MPW version 3.2.x and with Think C versions 5.0 to 5.0.4.
  701. The section “AppleTalk Multiple Node Architecture” discusses the new program interfaces to the AppleTalk Multiple Node Architecture. The new architecture was developed to support multiple node capability on the Macintosh computer, which allows the Macintosh to present itself as separate entities, or unique nodes on the network. The AppleTalk Remote Access program uses multinode capability to implement Remote Access functionality. This section presents the Datagram Delivery Protocol (DDP) interface for multinode AppleTalk for applications to take advantage of this new functionality. This Note, however, does not discuss the Remote Access program.
  702. The section “New for AppleTalk ADEVs” presents the changes required of an ADEV’s 'atlk' code resource for compatibility with the AppleTalk Multinode Architecture. While we recommend that developers of Ethernet and token ring network hardware conform to the specifications of the Multivendor ADEV Architecture, this information is presented for those developers of network products for which Apple does not supply an ADEV.
  703. The final section, “AppleTalk Version Information,” lists the various versions of AppleTalk, and the new products that require the support of the AppleTalk version.
  704. Where Can I Get the Latest Version of AppleTalk?
  705. For testing purposes, the latest version of AppleTalk and related software is available on the latest Developer CD Series disc, on AppleLink on the Developer Services Bulletin Board, and on the Internet through anonymous FTP to ftp.apple.com (130.43.2.3). It can be installed by using the Network Software Installer.
  706. The 'atkv' Gestalt Selector
  707. The 'atkv' Gestalt selector is available beginning with AppleTalk version 56 to provide more complete version information regarding AppleTalk, and as an alternative to the existing 'atlk' Gestalt selector. Beginning with AppleTalk version 54, the 'atlk' Gestalt selector was available to provide basic version information. The 'atlk' selector is not available when AppleTalk is turned off in the Chooser. It is important to note that the information between the two resources is provided in a different manner. Calling Gestalt with the 'atlk' selector provides the major revision version information in the low-order byte of the function result. Calling Gestalt with the 'atkv' selector provides the version information in a manner similar to the 'vers' resource. The format of the LONGINT result is as follows:
  708.     byte;                        /* Major revision */
  709.     byte;                        /* Minor revision */
  710.     byte        development = 0x20,        /* Release stage  */
  711.             alpha = 0x40,
  712.             beta = 0x60,
  713.             final = 0x80, /* or */ release = 0x80;
  714.     byte;                        /* Nonfinal release # */
  715. For example, passing the 'atkv' selector in a Gestalt call under AppleTalk version 57 gives the following LONGINT result: 0x39008000.
  716. Note: With the release of the System 7 Tuner product, AppleTalk will not be loaded at startup, if prior to the previous shutdown AppleTalk was turned off in the Chooser. Under this circumstance, the 'atkv' selector is not available. If the 'atkv' selector is not available under System 7, this is an indicator that AppleTalk cannot be turned on without doing so in the Chooser and rebooting the system.
  717. Sample Socket Listener
  718. The preferred AppleTalk calls presented in Inside Macintosh Volume V, page 513, do not include a preferred style call for DDPRead. As a result developers are faced with the prospect of writing their socket listeners and using the POpenSkt function when upgrading their programs. Inside Macintosh Volume II, page 324, presents an overview of how socket listeners should function. Inside Macintosh states that socket listeners, as well as protocol handlers, need to be written in assembly code, since parameters are passed in registers. To assist high-level programmers with implementing a socket listener, the generic listener code is provided. The following code demonstrates how to do the following:
  719. •    buffer multiple packets
  720. •    return DDP/LAP header information that has already been read into the Read Header Area (RHA) by DDP
  721. •    calculate and compare the packet checksum when a packet uses a long DDP header, and includes the checksum value
  722. Some of the things that the listener sample does not do, which you might wish to implement, are the following:
  723. •    Check the DDP type and ignore any packets that don’t match the desired type(s) that you’re interested in.
  724. •    Check the source node ID and ignore any packets that don’t come from the desired node(s).
  725. •    If the socket listener is used by more than one socket, it could route the packets differently based on the socket number found in D0.
  726. •    The socket listener does not handle the implementation of a completion routine to be executed when the packet is processed.
  727. The example listener code includes an initialization routine which the listener client uses to notify the listener code of the “available” and “used” buffer queues. A high-level procedure is provided to demonstrate the initialization of the listener, and the use of the socket listener.
  728. Socket Listener Review
  729. The reader is advised to refer to Inside Macintosh Volume II, pages 324 to 330, for a description of protocol handlers, socket listeners, and data reception in the AppleTalk Manager over LocalTalk. The same architecture applies to AppleTalk on Ethernet and token ring. With the advent of AppleTalk Phase 2, the size of the Read Header Area (RHA) has been expanded to accommodate the long DDP header.
  730. After every ReadPacket or ReadRest call, the listener code must check the Z (Zero) condition code for errors. If an error is detected from ReadPacket, the code must not call ReadRest. 
  731. It is the responsibility of the socket listener code to check for the existence of the DDP checksum. In contrast with the Frame Check Sequence that the hardware uses to verify the frame, the DDP checksum is implemented in extended DDP headers to verify that the packet data is not corrupted by memory or data bus errors within routers on the internet. If the checksum has been entered, then the socket listener code must calculate the checksum after the packet has been read in, and compare the computed value with the passed checksum value. The sample listener code demonstrates this check and calculation of the checksum. The listener code sets a flag that the program can check to determine whether the checksum matched or not.
  732. The record structure presented in this sample returns the DDP type, destination node ID, source address in AddrBlock format, the hop count, the size of the packet, a flag to indicate whether a checksum error occurred, followed by the actual datagram. The record structure can be extended to return additional information, such as the tick count at the time the socket handler was called. 
  733. Timing Considerations for LocalTalk
  734. If LocalTalk is being used, your socket listener has less than 95 microseconds (best case) to read more data with a ReadPacket or ReadRest call. If you need more time, you might consider reading another 3 bytes into the RHA to buy another 95 microseconds. Remember that the RHA may only have 8 bytes still available.
  735. Register Usage
  736. When the socket listener is called, the registers will be set up as follows:
  737.     Register(s)    Contents
  738.     A0-A1    SCC addresses used by MPP
  739.     A2        Pointer to MPP’s local variables
  740.     A3        Pointer to next free byte in RHA
  741.     A4        Pointer to ReadPacket {JSR (A4)} and ReadRest {JSR 2(A4)}                jump table
  742.     D0        This packet’s destination socket number
  743.     D1        Number of bytes left to read in packet
  744. •     Registers D0, D2, and D3 can be used freely throughout the socket listener. A6, and D4 to D7 must be preserved.
  745. •     From entry to socket listener until ReadRest is called:
  746.     The A5 register can be used.
  747.     Registers A0–A2, A4, and D1 must be preserved.
  748. •    From ReadRest until exit from socket listener:
  749.     The A5 register must be preserved.
  750.     Registers A0–A3 and D0–D3 are free to use.
  751. You should assume only 8 bytes are still available in the RHA for your use. The RHA will contain one of the following:
  752. Socket Listener Overview
  753. The sample socket listener utilizes two standard operating system (OS) queues (see Inside Macintosh Volume II, page 372), a free queue of available buffers that the listener uses to fill with incoming datagrams. The second linked list is a used queue of buffers that the listener has processed, but that have not been processed by the listener client. The SL_InitSktListener routine is called to pass the listener the pointers to the two OS queues. 
  754. When the listener is called to process a packet, the listener checks whether there is an available buffer record in the free queue by checking that qHead element of the free queue is not nil. If so, then the listener sets register A3 to point to the buffer_data element of the record and calls the ReadRest routine. If there is no available buffer record, the packet is ignored by calling ReadRest with a buffer size value of 0. Maybe the next time a packet is handled, a buffer will be available. If an error occurs during the ReadRest function, then the listener simply returns to the caller.
  755. If the packet is successfully read, the listener processes the header information. The header information has been stored by the hardware driver in the MPP local variable space pointed to in register A2. The listener code fills in the hop count field of the packet buffer record and determines the packet length. The listener then figures out whether it is dealing with a short or extended DDP header and fills in the remaining fields of the packet buffer. A check is made to determine whether the checksum field of the DDP header is nonzero. If the field is nonzero, the value is passed to the SL_DoChkSum function to verify that the resulting checksum is zero. If the resulting checksum is nonzero, the buffer_CheckSum field is set to ckSumErr, -3103, otherwise the field is set to noErr. Finally, the listener Enqueues the packet buffer into the used queue and Dequeues it from the free queue before returning to the caller.
  756. The calling program periodically checks the QHead element of the used queue. When QHead is no longer nil, a packet is available for processing. The program processes the packet buffer. When finished, the packet buffer is Enqueued into the free queue and Dequeued from the used queue. The program might then check for additional packets in the used queue and process them in the same manner.
  757. The program needs to define a sufficient number of packet buffers so that the listener has buffers available in the free queue between times when the program checks the used queue and processes incoming packets.
  758. Socket Listener Assembler Code
  759. ;_________________________________________________________________________
  760. ;
  761. ; Socket Listener Sample
  762. ;
  763. ; 3/92 Jim Luther,  Apple DTS
  764. ;
  765. ; ©1992 Apple Computer, Inc.
  766. ;_________________________________________________________________________
  767.     INCLUDE    'QuickEqu.a'
  768.     INCLUDE    'ToolEqu.a'
  769.     INCLUDE    'SysEqu.a'
  770.     INCLUDE    'Traps.a'
  771.     INCLUDE    'ATalkEqu.a'
  772.     INCLUDE    'SysErr.a'
  773. ;
  774. ;
  775. ; Record Types
  776. ;
  777. ;_________________________________________________________________________
  778. QHdr                  RECORD    0
  779. qFlags                DS.W      1
  780. qHead                 DS.L      1
  781. qTail                 DS.L      1
  782.                       ENDR
  783. PacketBuffer          RECORD    0
  784. qLink                 DS.L      1
  785. qType                 DS.W      1
  786. buffer_Type           DS.W      1            ; DDP Type
  787. buffer_NodeID         DS.W      1            ; Destination node
  788. buffer_Address        DS.L      1            ; Source address in AddrBlock format
  789. buffer_Hops           DS.W      1            ; Hop count
  790. buffer_ActCount       DS.W      1            ; length of DDP datagram
  791. buffer_CheckSum       DS.W      1            ; Chksum error returned here (cksumErr                              ; or noErr)
  792. buffer_Data           DS.B      ddpMaxData   ; the DDP datagram
  793.                       ENDR
  794. ;_________________________________________________________________________
  795. ;
  796. ; Local Variables
  797. ;
  798. ;_________________________________________________________________________
  799. SL_Locals    PROC
  800.         ENTRY free_queue,used_queue,current_qelem
  801. free_queue        DC.L    0        ; pointer to freeQ QHdr - initialized by                           ; InitSktListener
  802. used_queue        DC.L    0        ; pointer to usedQ QHdr - initialized by                           ; InitSktListener  
  803. current_qelem     DC.L    0        ; pointer to current PacketBuffer record
  804.                                    ; initialized by InitSktListener, then
  805.                                    ; set by socket listener after every packet.
  806.                                    ; NIL if no buffer is available.
  807.     ENDP
  808. ;_________________________________________________________________________
  809. ;
  810. ; SL_DoChksum - accumulate ongoing checksum (from Inside Macintosh)
  811. ;
  812. ;    Input:
  813. ;     D1 (word) = number of bytes to checksum
  814. ;     D3 (word) = current checksum
  815. ;     A1 points to the bytes to checksum
  816. ;
  817. ;    Return:
  818. ;     D0 is modified
  819. ;     D3 (word) = accumulated checksum
  820. ;_________________________________________________________________________
  821. SL_DoChksum    PROC
  822.     CLR.W      D0                    ; Clear high byte
  823.     SUBQ.W     #1,D1                 ; Decrement count for DBRA
  824. ChksumLoop:
  825.     MOVE.B     (A1)+,D0              ; read a byte into D0
  826.     ADD.W      D0,D3                 ; accumulate checksum
  827.     ROL.W      #1,D3                 ; rotate left one bit
  828.     DBRA       D1,ChksumLoop         ; loop if more bytes
  829.     RTS
  830.     ENDP
  831. ;_________________________________________________________________________
  832. ;
  833. ; SL_TheListener
  834. ;
  835. ;_________________________________________________________________________
  836. ;_________________________________________________________________________
  837. ;
  838. ; SL_TheListener - process packets received at the designated socket
  839. ;
  840. ;    Input:
  841. ;     D0 (byte) = packet's destination socket number
  842. ;     D1 (word) = number of bytes left to read in packet
  843. ;     A0 points to the bytes to checksum
  844. ;     A1 points to the bytes to checksum
  845. ;     A2 points to MPP's local variables
  846. ;     A3 points to next free byte in Read Header Area
  847. ;     A4 points to ReadPacket and ReadRest jump table
  848. ;
  849. ;    Return:
  850. ;     D0 is modified
  851. ;     D3 (word) = accumulated checksum
  852. ;_________________________________________________________________________
  853. SL_TheListener  PROC    EXPORT
  854.     WITH    PacketBuffer
  855. ; get pointer to current PacketBuffer
  856. GetBuffer:
  857.     LEA       current_qelem,A3                ; get the pointer to the PacketBuffer                            ; to use
  858.     MOVE.L    (A3),A3
  859.     MOVE.L    A3,D0                           ; if no PacketBuffer
  860.     BEQ.S     NoBuffer                        ; then ignore packet
  861. ; read rest of packet into PacketBuffer.datagramData
  862.     MOVE.L    D1,D3                           ; read rest of packet
  863.     LEA       buffer_data(A3),A3              ; A3 = ^bufferData
  864.     JSR       2(A4)                           ; ReadRest
  865.     BEQ.S     ProcessPacket                   ; If no error, continue
  866.     BRA       RcvRTS                          ; there was an error, so ignore packet
  867. ; No buffer; ignore the packet
  868. NoBuffer      CLR D3                          ; Set to ignore packet (buffer size =                            ; 0)
  869.     JSR       2(A4)                           ; ReadRest
  870.     BRA       GetNextBuffer                   ; We missed this packet, but maybe                            ; there will be a buffer for the next                            ; packet…
  871. ; Process the packet you just read in.
  872. ; ReadRest has been called so registers A0-A3 and D0-D3 are free to use.
  873. ; We'll use registers this way:
  874. PktBuff         EQU    A0        ; the current PacketBuffer
  875. MPPLocals       EQU    A2        ; pointer to MPP's local variables (still set up 
  876.                                  ;  from entry to socket listener)
  877. HopCount        EQU    D0        ; used to get the hop count
  878. DatagramLength  EQU    D1        ; used to determine the datagram length
  879. SourceNetAddr   EQU    D2        ; used to build the source network address
  880. ProcessPacket:
  881.     LEA        current_qelem,PktBuff          ; PktBuff = current_qelem
  882.     MOVE.L     (PktBuff),PktBuff
  883. ; do everything that's common to both long and short DDP headers
  884. ; first, clear buffer_Type and buffer_NodeID to ensure their high bytes are 0
  885.     CLR.W      buffer_Type(PktBuff)           ; clear buffer_Type
  886.     CLR.W      buffer_NodeID(PktBuff)         ; clear buffer_NodeID
  887. ; clear SourceNetAddr to prepare to build network address
  888.     MOVEQ      #0,SourceNetAddr               ; build the network address in                                ; SourceNetAddr
  889. ; get the hop count
  890.     MOVE.W     toRHA+lapHdSz+ddpLength(MPPLocals),HopCount ; Get hop/length field
  891.     ANDI.W     #DDPHopsMask,HopCount          ; Mask off the hop count bits
  892.     LSR.W      #2,HopCount                    ; shift hop count into low bits of high byte 
  893.     LSR.W      #8,HopCount                    ; shift hop count into low byte
  894.     MOVE.W     HopCount,buffer_Hops(PktBuff)  ; and move it into the PacketBuffer
  895. ; get the packet length (including the DDP header)
  896.     MOVE.W     toRHA+lapHdSz+ddpLength(MPPLocals),DatagramLength ; Get length field
  897.     ANDI.W     #ddpLenMask,DatagramLength     ; Mask off the hop count bits
  898. ; now, find out if the DDP header is long or short
  899.     MOVE.B     toRHA+lapType(MPPLocals),D3    ; Get LAP type
  900.     CMPI.B     #shortDDP,D3                   ; is this a long or short DDP header?
  901.     BEQ.S      IsShortHdr                     ; skip if short DDP header
  902. ; it's a long DDP header
  903.     MOVE.B     toRHA+lapHdSz+ddpType(MPPLocals),buffer_Type+1(PktBuff) ; get DDP                                            ; type
  904.     MOVE.B     toRHA+lapHdSz+ddpDstNode(MPPLocals),buffer_NodeID+1(PktBuff) 
  905.                                               ; get destination node from LAP header
  906.     MOVE.L     toRHA+lapHdSz+ddpSrcNet(MPPLocals),SourceNetAddr 
  907.                                               ; source network in hi word
  908.                                               ; source node in lo byte
  909.     LSL.W      #8,SourceNetAddr               ; shift source node up to high byte of                            ; low word
  910.                                               ; get source socket from DDP header
  911.     MOVE.B     toRHA+lapHdSz+ddpSrcSkt(MPPLocals),SourceNetAddr 
  912.     SUB.W      #ddpType+1,DatagramLength      ; DatagramLength = number of bytes in                            ; datagram
  913.     BRA.S      MoveToBuffer
  914. ; checksum time…
  915.     TST.W      toRHA+lapHdSz+ddpChecksum(MPPLocals) ;Does packet have checksum?
  916.     BEQ.S      noChecksum
  917. ; Calculate checksum over DDP header
  918.     MOVE.L     DatagramLength,-(SP)           ; save DatagramLength (D1)
  919.     CLR        D3                             ; set checksum to zero
  920.     MOVEQ      #ddphSzLong-ddpDstNet,D1       ; D1 = length of header part to                                ; checksum
  921.                                               ; pointer to dest network number in                            ; DDP header
  922.     LEA        toRHA+lapHdSz+ddpDstNet(MPPLocals),A1 
  923.     JSR        SL_DoChksum                    ; checksum of DDP header part 
  924.                                               ; (D3 holds accumulated checksum)
  925. ; Calculate checksum over data portion (if any)
  926.     MOVE.L     buffer_Data(PktBuff),A1        ; pointer to datagram
  927.     MOVE.L     (SP)+,DatagramLength           ; restore DatagramLength (D1)
  928.     MOVE.L     DatagramLength,-(SP)           ; save DatagramLength (D1) 
  929.                                               ;  before calling SL_DoChksum
  930.     BEQ.S      TestChecksum                   ; don't checksum datagram if its
  931.                            ; length = 0
  932.     JSR        SL_DoChksum                    ; checksum of DDP datagram part 
  933.                                               ; (D3 holds accumulated checksum)
  934. TestChecksum:
  935.     MOVE.L     (SP)+,DatagramLength           ; restore DatagramLength (D1)
  936. ; Now make sure the checksum is OK.
  937.     TST.W      D3                             ; is the calculated value zero?
  938.     BNE.S      NotZero                        ; no -- go and use it
  939.     SUBQ.W     #1,D3                          ; it is 0; make it -1
  940. NotZero:
  941.     CMP.W      toRHA+lapHdSz+ddpChecksum(MPPLocals),D3
  942.     BNE.S      ChecksumErr                    ; Bad checksum
  943.     MOVE.W     #0,buffer_CheckSum(A0)         ; no errors
  944.     BRA.S      noChecksum
  945. ChecksumErr:
  946.     MOVE.W     #ckSumErr,buffer_CheckSum(PktBuff) ; checksum error
  947. noChecksum:
  948.     BRA.S      MoveToBuffer
  949. ; it's a short DDP header
  950. IsShortHdr:
  951.     MOVE.B     toRHA+lapHdSz+sddpType(MPPLocals),buffer_Type+1(PktBuff) ; get DDP                                         ; type
  952.     MOVE.B     toRHA+lapDstAdr(MPPLocals),buffer_NodeID+1(PktBuff) 
  953.                                                ; get destination node from LAP                             ; header
  954.     MOVE.B     toRHA+lapSrcAdr(MPPLocals),SourceNetAddr ; get source node from LAP                                   ; header
  955.     LSL.W      #8,SourceNetAddr                ; shift src node up to high byte of                             ; low word
  956.     MOVE.B     toRHA+lapHdSz+sddpSrcSkt(MPPLocals),SourceNetAddr 
  957.                                                ; get source socket from short DDP                             ; header
  958.     SUB.W      #sddpType+1,DatagramLength      ; DatagramLength = number of bytes in                             ; datagram
  959. MoveToBuffer:
  960.     MOVE.L     SourceNetAddr,buffer_Address(PktBuff) 
  961.                                                ;move source network address into                             ; PacketBuffer
  962.     MOVE.W     DatagramLength,buffer_ActCount(PktBuff) 
  963.                                                ; move datagram length into                                 ; PacketBuffer
  964. ; Now that we're done with the PacketBuffer, enqueue it into the usedQ and get
  965. ; another buffer from the freeQ for the next packet.
  966.     LEA        used_queue,A1                   ; A1 = ^used_queue
  967.     MOVE.L     (A1),A1                         ; A1 = used_queue (pointer to usedQ)
  968.     _Enqueue                                   ; put the PacketBuffer in the usedQ
  969. GetNextBuffer:
  970.     LEA        free_queue,A1                   ; A1 = ^free_queue
  971.     MOVE.L     (A1),A1                         ; A1 = free_queue (pointer to freeQ)
  972.     LEA        current_qelem, A0               ; copy freeQ.qHead into current_qelem
  973.     MOVE.L     qHead(A1),(A0)
  974.     MOVEA.L    qHead(A1),A0                    ; A0 = freeQ.qHead
  975.     _Dequeue
  976. RcvRTS:
  977.     RTS                                        ; return to caller
  978.     ENDP
  979. ;_________________________________________________________________________
  980. ; Function SL_InitSktListener(freeQ, usedQ: QHdrPtr): OSErr
  981. ;
  982. ;
  983. SL_InitSktListener PROC EXPORT
  984. StackFrame     RECORD    {A6Link},DECR     ; build a stack frame record
  985. Result1        DS.W      1                 ; function's result returned to caller
  986. ParamBegin     EQU       *                 ; start parameters after this point
  987. freeQ          DS.L      1                 ; freeQ parameter
  988. usedQ          DS.L      1                 ; usedQ parameter
  989. ParamSize      EQU       ParamBegin-*      ; size of all the passed parameters
  990. RetAddr        DS.L      1                 ; placeholder for return address
  991. A6Link         DS.L      1                 ; placeholder for A6 link
  992. LocalSize      EQU       *                 ; size of all the local variables
  993.                ENDR
  994.     WITH       StackFrame,QHdr             ; use these record types
  995.     LINK       A6,#LocalSize               ; allocate our local stack frame
  996. ; copy the queue header pointers into our local storage for use in the listener
  997.     LEA        used_queue,A0               ; copy usedQ into used_queue
  998.     MOVE.L     usedQ(A6),(A0)
  999.     LEA        free_queue,A0               ; copy freeQ into free_queue
  1000.     MOVE.L     freeQ(A6),(A0)
  1001. ; dequeue the first buffer record from freeQ and set current_qelem to it
  1002.     MOVEA.L    freeQ(A6),A1                ; A1 = ^freeQ
  1003.     LEA        current_qelem, A0           ; copy freeQ.qHead into current_qelem
  1004.     MOVE.L     qHead(A1),(A0)
  1005.     MOVEA.L    qHead(A1),A0                ; A0 = freeQ.qHead
  1006.     _Dequeue
  1007.     MOVE.W     D0,Result1(A6)              ; Return status
  1008. @1  UNLK       A6                          ; destroy the link
  1009.     MOVEA.L    (SP)+,A0                    ; pull off the return address
  1010.     ADDA.L     #ParamSize,SP               ; strip all of the caller's parameters
  1011.     JMP        (A0)                        ; return to the caller
  1012.     ENDP
  1013.     END                                    ; end of this source file
  1014. Initializing the Socket Listener
  1015. To initialize the socket listener, define the free and used queue QHdr variables. You’ll need to define a PacketBuffer structure to match the record structure defined in the socket listener code. If you add any new fields, then you need to modify the PacketBuffer structure defined in the listener code. In the sample below, an array of 10 PacketBuffers is declared.  Initialize the buffer packets, then queue them into the free queue using the _Enqueue trap. Call SL_InitSktListener and pass the addresses of the QHdr variable for the free and used queues. The following Pascal code demonstrates this process:
  1016. USES MEMTYPES, QUICKDRAW, OSINTF, APPLETALK;
  1017. CONST
  1018.   ddpMaxData = 586;
  1019. TYPE
  1020.     PacketBuffer = RECORD
  1021.         qLink: QElemPtr;
  1022.         qType: Integer;
  1023.         buffer_Type: Integer;
  1024.         buffer_NodeID: Integer;
  1025.         buffer_Address: AddrBlock;
  1026.         buffer_Hops: Integer;
  1027.         buffer_ActCount: Integer;
  1028.         buffer_CheckSum: OSErr;
  1029.         buffer_Data: ARRAY[1..ddpMaxData] OF SignedByte;
  1030.     END;
  1031. VAR
  1032.     freeQ, usedQ: QHdr;
  1033.     Buffers: ARRAY[1..10] OF PacketBuffer;
  1034. PROCEDURE SL_TheListener;
  1035. External;
  1036. FUNCTION SL_InitSktListener (freeQ, usedQ: QHdrPtr): OSErr;
  1037. External;
  1038. PROCEDURE SetUpSocketListener;
  1039.     VAR
  1040.         err: OSErr;
  1041.         i: Integer;
  1042.     BEGIN
  1043.         freeQ.QHead := NIL;                  { initialize to nil to indicate empty                             queue }
  1044.         freeQ.QTail := NIL;                  { initialize to nil to indicate end of                             queue }
  1045.         usedQ.QHead := NIL;                  { initialize to nil to indicate empty                             queue }
  1046.         usedQ.QTail := NIL;                  { initialize to nil to indicate end of                             queue }
  1047.         FOR i := 1 TO 10 DO
  1048.             Enqueue(@Buffers[i], @freeQ);
  1049.         err := SL_InitSktListener(@freeQ, @usedQ);
  1050.         IF err <> noErr THEN
  1051.             BEGIN
  1052.                 { Perform error processing here }
  1053.             END;
  1054.     END;
  1055. For C programmers, the initialization code is as follows:
  1056. #include    <types.h>
  1057. #include    <appletalk.h>
  1058. #include    <OSUtils.h>
  1059. #include    <stdio.h>
  1060. #define ddpMaxData   586
  1061. typedef struct {
  1062.     QElemPtr    qLink;
  1063.     short       qType;
  1064.     short       buffer_type;        /* DDP Type */
  1065.     short       buffer_NodeID;      /* Destination Node */
  1066.     AddrBlock   buffer_Address;     /* Source Address in AddrBlock format */
  1067.     short       buffer_Hops;        /* Hop count */
  1068.     short       buffer_ActCount;    /* length of DDP datagram */
  1069.     OSErr       buffer_CheckSum;    /* Checksum returned here */
  1070.     char        buffer_Data[ddpMaxData]; /* the DDP datagram */
  1071. } PacketBuffer;
  1072. QHdr          freeQ, usedQ;
  1073. PacketBuffer  buffers[10];
  1074. extern void SL_THELISTENER();
  1075. extern pascal OSErr SL_INITSKTLISTENER (freeQ, usedQ: QHdrPtr): OSErr;
  1076. void SetUpSocketListener()
  1077. {
  1078.     OSErr  err;
  1079.     short  i;
  1080.     freeQ.QHead = nil;              /* initialize to nil to indicate empty queue */
  1081.     freeQ.QTail = nil;              /* initialize to nil to indicate end of queue */
  1082.     usedQ.QHead = nil;              /* initialize to nil to indicate empty queue */
  1083.     usedQ.QTail = nil;              /* initialize to nil to indicate end of queue */
  1084.     for (i = 0; i < 10; i++)
  1085.         Enqueue((QElemPtr)&buffers[i], &freeQ);
  1086.     err = SL_INITSKTLISTENER (&freeQ, &usedQ);
  1087.     if (err != noErr) {
  1088.         /* perform error processing here */
  1089.     }
  1090. }
  1091. Using the Socket Listener
  1092. The socket listener is set in use with the POpenSkt function, or with the more specific POpenATPSkt function. The program then periodically checks the usedQ.QHead value to determine whether the socket listener has processed a packet. If so, the packet is processed, Dequeued from the used queue, and Enqueued into the free queue. It’s also possible for the same socket listener to be used by separate processes in the program. If so, the program must scan the list for the desired packet(s). Note that if multiple packets are expected, it is possible that the program may process the first packet before the listener processes the second packet. The program needs to be designed to check the usedQ.QHead value later for the additional packets.
  1093. TYPE
  1094.     PacketBuffer = RECORD
  1095.         qLink: QElemPtr;
  1096.         qType: Integer;
  1097.         buffer_Type: Integer;
  1098.         buffer_NodeID: Integer;
  1099.         buffer_Address: AddrBlock;
  1100.         buffer_Hops: Integer;
  1101.         buffer_ActCount: Integer;
  1102.         buffer_CheckSum: OSErr;
  1103.         buffer_Data: ARRAY[1..ddpMaxData] OF SignedByte;
  1104.     END;
  1105.     PacketPtr = ^PacketBuffer;
  1106. VAR
  1107.     freeQ, usedQ: QHdr;
  1108.     bufPtr : PacketPtr;
  1109.     .
  1110.     .
  1111.     .
  1112.     WHILE (usedQ.QHead <> nil) DO             { check if packet available for                                  processing }
  1113.         BEGIN
  1114.             bufPtr := PacketPtr(usedQ.QHead);  { get the packet ptr }
  1115.             IF (Dequeue(QElemPtr(bufPtr), @usedQ) <> noErr) THEN
  1116.                 BEGIN
  1117.                  { Process the packet information }
  1118.                  Enqueue(QElemPtr(bufPtr), @freeQ); { requeue the packet buffer for                                 use. }
  1119.                 END
  1120.             ELSE
  1121.                 BEGIN
  1122.                     { error occurred dequeueing packet - perform error processing              here }
  1123.                 END;
  1124.         END;
  1125. For C Programmers, the  socket listener code is used as follows:
  1126. typedef struct {
  1127.     QElemPtr    qLink;
  1128.     short       qType;
  1129.     short       buffer_type;        /* DDP Type */
  1130.     short       buffer_NodeID;      /* Destination Node */
  1131.     AddrBlock   buffer_Address;     /* Source Address in AddrBlock format */
  1132.     short       buffer_Hops;        /* Hop count */
  1133.     short       buffer_ActCount;    /* length of DDP datagram */
  1134.     OSErr       buffer_CheckSum;    /* Checksum returned here */
  1135.     char        buffer_Data[ddpMaxData]; /* the DDP datagram */
  1136. } PacketBuffer;
  1137. typedef PacketBuffer *PacketPtr;
  1138. QHdr       freeQ, usedQ;
  1139. PacketPtr  bufPtr;
  1140.     .
  1141.     .
  1142.     .
  1143.     while (usedQ.QHead != nil) {               /* check if packet available for                                processing */
  1144.         bufPtr = (PacketPtr)usedQ.QHead;       /* get the packet ptr */
  1145.         if (Dequeue(QElemPtr(bufPtr), &usedQ) == noErr {
  1146.             { Process the packet information }
  1147.             Enqueue(QElemPtr(bufPtr), &freeQ);  /* requeue the packet buffer for                                 use. */
  1148.         }
  1149.         else {
  1150.             /* error occurred dequeueing packet - perform error processing here */
  1151.         }
  1152.     }
  1153. The AppleTalk Transition Queue
  1154. The AppleTalk Transition Queue keeps applications and other resident processes on the Macintosh informed of AppleTalk events, such as the opening and closing of AppleTalk drivers, or changes to the Flagship name (to be discussed later in this Note). A comprehensive discussion of the AppleTalk Transition Queue is presented in Inside Macintosh Volume VI, Chapter 32. New to the AppleTalk Transition Queue are messages regarding the Flagship Naming Service, the AppleTalk Multiple Node Architecture (also to be discussed later in this Note), changes to processor speed that may affect LocalTalk timers, and a transition to indicate change of the network cable range. 
  1155. Later in this section is a sample Transition Queue procedure in both C and Pascal that includes the known transition selectors. There is also a sample Pascal source for determining whether the LAP Manager version 53 or later exists. Calling LAPAddATQ for AppleTalk versions 52 and earlier will result in a system crash since the LAP Manager is not implemented prior to AppleTalk version 53. The Boolean function, LAPMgrExists, should be used instead of checking the low-memory global LAPMgrPtr, $0B18.
  1156. Bug With LAPAddATQ and LAPRmvATQ Glue Code
  1157. A bug exists in the glue code for the LAPAddATQ and for the LAPRmvATQ routines in the Interface.o file. The same glue code is used with the Think C version 5.0.x product and will affect those users as well. 
  1158. In the glue code, these calls use the Pascal stack calling convention by allocating memory on the stack for the OSErr result. The ATQEntryPtr is then pushed onto the stack and the LAP Manager is called. Upon return from a JSR instruction to the LAP Manager code, the return address is placed in register A0 and the stack incremented. The glue code should then move the 2-byte result onto the stack into the location reserved for the result. Instead, the glue code decrements the stack pointer by 2 bytes before moving the result onto the stack. The glue code jumps to the return address in register A0. Upon return, the stack is off by 2 bytes. If local variables are used and are referenced from the stack pointer in register A7, following the return from these LAP Manager calls, access to the local variables may not be correct. 
  1159. The following Assembler glue code is supplied for MPW users to assemble and link with their programs. For the remainder of this Tech Note, the call LAPAddATQFix and LAPRmvATQFix will be used instead and refer to the following code. For Think C programmers, the same functions are presented using in-line Assembler. For Think Pascal programmers, one solution is to compile the Think C code and to link with the resulting Library file.
  1160. ;_________________________________________________________________________
  1161. ;
  1162. ; ATQFix.a
  1163. ;_________________________________________________________________________
  1164. ;
  1165. ; DTS Code Sample
  1166. ;
  1167. ; ©1992 Apple Computer, Inc.
  1168. ;
  1169. ; Replacement code for LAPAddATQ and LAPRmvATQ in which 
  1170. ; the glue code in Interface.o does not restore the stack to
  1171. ; its original condition.  Use the following code as opposed
  1172. ; to that in the Interface.o file.
  1173. ;
  1174. ;_________________________________________________________________________
  1175. ;
  1176. ; interface
  1177. ; pascal OSErr LAPAddATQFix(ATQEntryPtr theATQEntry);
  1178. ; pascal OSErr LAPRmvATQFix(ATQEntryPtr theATQEntry);
  1179. LAPAddATQFix   PROC   EXPORT
  1180.            MOVE.W     #$0017,D0       ; D0 selector $0017 = LAPAddATQ
  1181.            MOVEA.L    $0004(A7),A0    ; A0 -> ATQ Proc
  1182.            MOVEA.L    $0B18,A1        ; Set up to call LAP Manager
  1183.            MOVE.L     (A7)+,(A7)      ; Move return address up 4 bytes
  1184.            JSR        $0002(A1)       ; call LAP Manager
  1185.            MOVEA.L    (A7)+,A0        ; Move return address into A0
  1186.            MOVE.W     D0,(A7)         ; Move result into space reserved on stack
  1187.            JMP        (A0)            ; Return
  1188.            ENDP
  1189. LAPRmvATQFix   PROC   EXPORT
  1190.            MOVE.W     #$0018,D0       ; D0 selector $0018 = LAPRmvATQ
  1191.            MOVEA.L    $0004(A7),A0    ; A0 -> ATQ Proc
  1192.            MOVEA.L    $0B18,A1        ; Set up to call LAP Manager
  1193.            MOVE.L     (A7)+,(A7)      ; Move return address up 4 bytes
  1194.            JSR        $0002(A1)       ; call LAP Manager
  1195.            MOVEA.L    (A7)+,A0        ; Move return address into A0
  1196.            MOVE.W     D0,(A7)         ; Move result into space reserved on stack
  1197.            JMP        (A0)            ; Return
  1198.            ENDP
  1199.            END
  1200. ;_________________________________________________________________________
  1201. ; End File: ATQFix.a
  1202. ;_________________________________________________________________________
  1203. For Think C programmers, the following code sample can be used. Think Pascal programmers can link with the library file produced by compiling this code with the Think C compiler.
  1204. /*
  1205.  *_________________________________________________________________________
  1206.  * File: ATQFix.c
  1207.  *_________________________________________________________________________
  1208.  *
  1209.  * DTS Code Sample
  1210.  *
  1211.  * ©1992 Apple Computer, Inc.
  1212.  *
  1213.  * Replacement code for LAPAddATQ and LAPRmvATQ for Think C programmers 
  1214.  * to fix the glue code to fix a bug in the Think C library supplied via 
  1215.  * the MPW Interface.o file.  The glue code does not restore the stack to
  1216.  * its original condition.  Use the following code as opposed
  1217.  * to that in the Think C library instead.
  1218.  *
  1219.  *_________________________________________________________________________
  1220.  */
  1221. #ifndef __TYPES__
  1222. #include <Types.h>
  1223. #endif
  1224. #define LAPAddATQCall    0x17
  1225. #define LAPRmvATQCall    0x18
  1226. #define LAPMgrPtr        0xB18
  1227. #define LAPMgrCall       2
  1228.  
  1229. /**********  Prototypes ****************************/
  1230. pascal OSErr LAPAddATQFix(ATQEntryPtr theATQEntry);
  1231. pascal OSErr LAPRmvATQFix(ATQEntryPtr theATQEntry);
  1232. pascal OSErr LAPAddATQFix(ATQEntryPtr theATQEntry)
  1233. {
  1234.         asm {
  1235.             MOVE.W     #LAPAddATQCall,D0          /* D0 selector $0017 = LAPAddATQ                                */
  1236.             MOVEA.L    theATQEntry,A0             /* A0 -> ATQ Proc */
  1237.             MOVEA.L    LAPMgrPtr,A1               /* Set up to call LAP Manager */
  1238.             JSR        LAPMgrCall(A1)             /* call LAP Manager */
  1239.             MOVE.W     D0,12(A6)                  /* move result in D0 onto the                                   stack */
  1240.         }
  1241. }
  1242. pascal OSErr LAPRmvATQFix(ATQEntryPtr theATQEntry)
  1243. {
  1244.         asm {
  1245.             MOVE.W     #LAPRmvATQCall,D0          /* D0 selector $0018 = LAPRmvATQ                                */
  1246.             MOVEA.L    theATQEntry,A0             /* A0 -> ATQ Proc */
  1247.             MOVEA.L    LAPMgrPtr,A1               /* Set up to call LAP Manager */
  1248.             JSR        LAPMgrCall(A1)             /* call LAP Manager */
  1249.             MOVE.W     D0,12(A6)                  /* move result in D0 onto the                                   stack */
  1250.         }
  1251. }
  1252. /*
  1253.  *_________________________________________________________________________
  1254.  * End file: ATQFix.c
  1255.  *_________________________________________________________________________
  1256.  */
  1257. Calling the AppleTalk Transition Queue
  1258. System software version 7.0 requires the use of the MPW version 3.2 interface files and libraries. The AppleTalk interface presents two new routines for calling all processes in the AppleTalk Transition Queue. Rather than use parameter block control calls as described in M.NW.AppleTalk2Mac, use the ATEvent procedure or the ATPreFlightEvent function to send transition notification to all queue elements. These procedures are discussed in Inside Macintosh Volume VI, Chapter 32.
  1259. Note:    You can call the ATEvent and ATPreFlightEvent routines only at virtual memory safe time. See the Memory Management chapter of Inside Macintosh Volume VI, Chapter 28, for information on virtual memory.
  1260. Standard AppleTalk Transition Constants
  1261. Use the following constants for the standard AppleTalk transitions:
  1262. CONST    ATTransOpen    = 0;     {open transition }
  1263.     ATTransClose    = 2;     {prepare-to-close transition }
  1264.     ATTransClosePrep    = 3;     {permission-to-close transition }
  1265.     ATTransCancelClose    = 4;     {cancel-close transition }
  1266.     ATTransNetworkTransition    = 5;     {.MPP Network ADEV Transition }
  1267.     ATTransNameChangeTellTask    = 6;     {change-Flagship-name transition }
  1268.     ATTransNameChangeAskTask    = 7;     {permission-to-change-Flagship-name                     transition }
  1269.     ATTransCancelNameChange    = 8;     {cancel-change-Flagship-name transition }
  1270.     ATTransCableChange    = 'rnge' {cable range change transition }
  1271.     ATTransSpeedChange    = 'sped' {change in cpu speed }
  1272. The following information concerns the new transitions from ATTransNetworkTransition through ATTransSpeedChange.
  1273.  
  1274. The Flagship Naming Service
  1275. System software version 7.0 allows the user to enter a personalized name by which her system will be published when connected to an AppleTalk network. The System 'STR ' resource ID –16413 is used to hold this name. The name (listed as Macintosh Name) can be up to 31 characters in length and can be set using the Sharing Setup Control Panel Device (cdev). This resource is different from the Chooser name, System 'STR ' resource ID –16096. When providing network services for a workstation, the Flagship name should be used so that the user can personalize his workstation name while maintaining the use of the Chooser name for server connection identification. It’s important to note that the Flagship name resource is available only from system software version 7.0. DTS recommends that applications not change either of these 'STR ' resources.
  1276. Applications taking advantage of this feature should place an entry in the AppleTalk Transition Queue to stay informed as to changes to this name. Three new transitions have been defined to communicate Flagship name changes between applications and other resident processes. Support for the Flagship Naming Service Transitions is provided starting from AppleTalk version 56. Note that AppleTalk version 56 can be installed on pre-7.0 systems; however, the Flagship Naming Service is available only from system software 7.0 and later.
  1277. The ATTransNameChangeAskTask Transition
  1278. From Assembly language, the stack upon calling looks as follows:
  1279. ATQEvent            RECORD   0
  1280. ReturnAddr          DS.L     1      ; address of caller
  1281. theEvent            DS.L     1      ; = 7; ID of ATTransNameChangeAskTask transaction
  1282. aqe                 DS.L     1      ; pointer to task record
  1283. infoPtr             DS.L     1      ; pointer to NameChangeInfo parameter block
  1284.                     ENDR
  1285. The NameChangeInfo record block is as follows
  1286. NameChangeInfoPtr: ^NameChangeInfo;
  1287. NameChangeInfo  = RECORD
  1288.                     newObjStr:      Str32;         {new Flagship name to change to }
  1289.                     name:           StringPtr;     {ptr to location to place ptr to                               process }
  1290.                                                    {name }
  1291.                   END;
  1292. The ATTransChangeNameAskTask is issued under system software version 7.0 to inform Flagship clients that a process wants to change the Flagship name. Each AppleTalk Transition Queue element that processes the ATTransChangeNameAskTask can inspect the NameChangeInfoPtr^.newObjStr to determine the new Flagship name. If you deny the request, you must set the NameChangeInfoPtr^.name pointer with a pointer to a Pascal string buffer containing the name of your application or to the nil pointer. The AppleTalk Transition Queue process returns this pointer. The requesting application can display a dialog notifying the user of the name of the application that refused the change request.
  1293. While processing this event, you can make synchronous calls to the Name-Binding Protocol (NBP) to attempt to register your entity under the new name. It is recommended that you register an entity using the new Flagship name while handling the ATTransChangeNameAskTask event. You should not deregister an older entity at this point. Your routine must return a function result of 0 in the D0 register, indicating that it accepts the request to change the Flagship name, or a nonzero value, indicating that it denies the request.
  1294. Warning:     DTS does not recommend that you change the Flagship name. The Sharing Setup cdev does not handle this event and the Macintosh name will not be updated to reflect this change if the cdev is open.
  1295. The ATTransNameChangeTellTask Transition
  1296. From Assembly language, the stack upon calling looks as follows:
  1297. ATQEvent    RECORD    0
  1298. ReturnAddr    DS.L    1    ; address of caller
  1299. theEvent    DS.L    1    ; = 6; ID of ATTransNameChangeTellTask transaction
  1300. aqe    DS.L    1    ; pointer to task record
  1301. infoPtr    DS.L    1    ; pointer to the new Flagship name
  1302.     ENDR
  1303. A process uses ATEvent to send the ATTransNameChangeTellTask to notify AppleTalk Transition Queue clients that the Flagship name is being changed. The LAP Manager then calls every routine in the AppleTalk Transition Queue that the Flagship name is being changed.
  1304. When the AppleTalk Manager calls your routine with a ATTransNameChangeTellTask transition, the third item on the stack is a pointer to a Pascal string of the new Flagship name to be registered. Your process should deregister any entities under the old Flagship name at this time. You can make synchronous calls to NBP to deregister an entity. Return a result of 0 in the D0 register.
  1305. Note:    When the AppleTalk Manager calls your process with a TellTask transition (that is, with a routine selector of ATTransNameChangeTellTask), you cannot prevent the Flagship name from being changed.
  1306. To send notification that your process intends to change the Flagship name, use the ATEvent function described above. Pass ATTransNameChangeTellTask as the event parameter and a pointer to the new Flagship name (Pascal string) as the infoPtr parameter.
  1307. The ATTransCancelNameChange Transition
  1308. From Assembly language, the stack upon calling looks as follows:
  1309. ATQEvent    RECORD    0
  1310. ReturnAddr    DS.L    1    ; address of caller
  1311. theEvent    DS.L    1    ; = 8; ID of ATTransCancelNameChange transaction
  1312. aqe    DS.L    1    ; pointer to task record
  1313.     ENDR
  1314. The ATTransCancelNameChange transition complements the ATTransNameChange-AskTask transition. Processes that acknowledged an ATTransNameChangeAskTask transition will be sent the ATTransCancelNameChange transition if a later process disallows the change of Flagship name. Your process should deregister any NBP entities registered during the ATTransNameChangeAskTask transition. You can make synchronous calls to NBP to deregister an entity. Return a result of 0 in the D0 register.
  1315. System 7.0 Sharing Setup cdev / Flagship Naming Service Interaction
  1316. The Flagship Naming Service is a new system service built into System 7. It is used to publish the workstation using the Flagship name. The Flagship Naming Service implements an AppleTalk Transition Queue element to respond to changes in the Flagship name. For example, the Sharing Setup cdev can be used to reset the Flagship name. When a new Macintosh (Flagship) name is entered in Sharing Setup, Sharing Setup sends an ATTransNameChangeAskTask message to the AppleTalk Transition Queue to request permission to change the Flagship name. The Flagship Naming Service receives the ATTransNameChangeAskTask transition and registers the new name under the type “Workstation” on the local network. Sharing Setup follows with the ATTransNameChangeTellTask to notify AppleTalk Transition Queue clients that a change in Flagship name will occur. The Flagship Naming Service responds by deregistering the workstation under the old Flagship name.
  1317. If an error occurs from the NBPRegister call, Flagship Naming Service returns a nonzero error (the error returned from NBPRegister) and a pointer to its name in the NameChangeInfoPtr^.Name field. Note that the Workstation name is still registered under the previous Flagship name at this point.
  1318. AppleTalk Remote Access Network Transition Event
  1319. AppleTalk Remote Access allows you to establish an AppleTalk connection between two Macintosh computers over standard telephone lines. If the Macintosh you dial-in to is on an AppleTalk network, such as LocalTalk or Ethernet, your Macintosh becomes, effectively, a node on that network. You are then able to use all the services on the new network. Given this new capability, it is important that services running on your Macintosh be notified when new AppleTalk connections are established and broken. For this reason, the ATTransNetworkTransition event has been added to AppleTalk version 57. With version 57 present, this event can be expected in system software version 6.0.5 or later.
  1320. Internally, both the AppleTalk Session Protocol (ASP) and the AppleTalk Data Stream Protocol (ADSP) have been modified to respond to this transition event. When a disconnect transition event is detected, these drivers close down sessions on the remote side of the connection.
  1321. The ATTransNetworkTransition Transition
  1322. From Assembly language, the stack upon calling looks as follows:
  1323. ATQEvent    RECORD    0    
  1324. ReturnAddr    DS.L    1    ; address of caller
  1325. theEvent    DS.L    1    ; = 5; ID of ATTransNetworkTransition
  1326. aqe    DS.L    1    ; pointer to task record
  1327. infoPtr    DS.L    1    ; pointer to the TNetworkTransition record
  1328.     ENDR
  1329. The TNetworkTransition record block is passed as follows:
  1330. TNetworkTransition    RECORD    0
  1331. private    DS.L    1    ; pointer used internally by AppleTalk                     Remote Access    
  1332. netValidProc    DS.L    1    ; pointer to the network validate procedure
  1333. newConnectivity    DS.B    1    ; true = new connectivity, false = loss               of connectivity
  1334.     ENDR
  1335. Network Transition Event for AppleTalk Remote Access
  1336. Network Transition events are generated by AppleTalk Remote Access to inform AppleTalk Transition Queue applications and resident processes that network connectivity has changed. The type of change is indicated by the NetTransPtr^.newConnectivity flag. If this flag is true, a connection to a new internet has taken place. In this case, all network addresses will be returned as reachable. If the newConnectivity flag is false, certain networks are no longer reachable. Since AppleTalk Remote Access is connection based, it has knowledge of where a specific network exists. AppleTalk Remote Access can take advantage of that knowledge during a disconnect to inform AppleTalk Transition Queue clients that a network is no longer reachable. This information can be used by clients to age out connections immediately rather than waiting a potentially long period of time before discovering that the other end is no longer responding.
  1337. When AppleTalk Remote Access is disconnecting, it passes a network validation hook in the TNetworkTransition record, NetTransPtr^.netValidProc. A client can use the validation hook to ask AppleTalk Remote Access whether a specific network is still reachable. If the network is still reachable, the validate function will return true. A client can then continue to check other networks of interest until the status of each one has been determined. After a client has finished checking networks, control returns to AppleTalk Remote Access where the next AppleTalk Transition Queue client is called.
  1338. The information the network validation hook returns is valid only if a client has just been called as a result of a transition. A client can validate networks only when she has been called to handle a Network Transition event. Note that the Network Transition event can be called as the result of an interrupt, so a client should obey all of the normal conventions involved with being called at this time (for example, don’t make calls that move memory and don’t make synchronous Preferred AppleTalk calls).
  1339. To check a network number for validity the client uses the network validate procedure to call AppleTalk Remote Access. This call is defined using C calling conventions as follows:
  1340. pascal long netValidProc(TNetworkTransition *thetrans, unsigned long theAddress);
  1341.     thetrans    -->    Pass in the TNetworkTransition record given to you when                 your transition handler was called.
  1342.     theAddress    -->    This is the network address you want checked. The                 format of theAddress is the same as AddrBlock as                     defined in Inside Macintosh II, page 281:
  1343.             Bytes 2 & 3 (High Word) - Network Number
  1344.             Byte 1 - Node Number
  1345.             Byte 0 (Low Byte) - Socket Number
  1346. Result codes        true    network is still reachable
  1347.             false    network is no longer reachable
  1348. AppleTalk Transition Queue handlers written in Pascal must implement glue code to use the netValidProc.
  1349. Cable Range Change Transition Event
  1350. The Cable Range Transition, ATTransCableChange, event informs AppleTalk Transition Queue processes that the cable range for the current network has changed. This can occur when a router is first seen, when the last router ages out, or when an RTMP broadcast packet is first received with a cable range that is different from the current range. The ATTransCableChange event is implemented beginning with AppleTalk version 57. Most applications should not need to process this event. With version 57 present, this event can be expected in system software version 6.0.5 and later.
  1351. The ATTransCableChange Transition
  1352. From Assembly language, the stack upon calling looks as follows:
  1353. ATQEvent    RECORD    0    
  1354. ReturnAddr    DS.L    1    ; address of caller
  1355. theEvent    DS.L    1    ; = 'rnge'; ID of ATTransCableChange
  1356. aqe    DS.L    1    ; pointer to task record
  1357. infoPtr    DS.L    1    ; pointer to the TNetworkTransition record
  1358.     ENDR
  1359. The TNewCRTrans record block is passed as follows:
  1360. TNewCRTrans    RECORD    0
  1361. newCableLo    DS.W    1    ; the new Cable Lo received from RTMP
  1362. newCableHi    DS.W    1    ; the new Cable Hi received from RTMP
  1363.     ENDR
  1364. The cable range is a range of network numbers starting from the lowest network number through the highest network number defined by a seed router for a network. All node addresses acquired on a network must have a network number within the defined cable range. For nonextended networks, the lowest and the highest network numbers are the same. If the cable range on the network changes, for example, if the router on the network goes down, the Cable Range Change event will be issued with the parameters described earlier in this Technical Note.
  1365. After receiving the event, a multinode application should use the new cable range to check if all the multinodes it obtained prior to the event are still valid. For the invalid multinodes, the application should issue the .MPP RemoveNode control call to get rid of invalid nodes. The .MPP AddNode control call can be issued immediately after removing invalid nodes to obtain new valid multinodes in the new cable range. This Cable Range Change Transition event will be issued only during system task time.
  1366. The Speed Change Transition Event
  1367. The ATTransSpeedChange Transition event is defined for applications that change CPU speed without rebooting, to notify time-dependent processes that such change has taken place. Such speed change occurs when altering the cache states on the 68030 or 68040 CPUs, or with third- party accelerator cards that allow speed changes on the fly via a cdev. Any process that alters the effective CPU speed should use the ATEvent to notify processes of this change. Issue the ATTransSpeedChange event only at SystemTask time! Any process that depends on changes to the CPU speed should watch for this event. The Speed Change Transition event is issued only during system task time.
  1368. One time-dependent code module is LocalTalk, whose low-level timer values must be recalculated when the CPU speed changes. Note that altering the cache state on the 68030 does not affect LocalTalk; however doing so on the 68040 does affect LocalTalk timers. This event must be sent by any application that toggles caching on the 68040 processor on the fly. If the cache is toggled and LocalTalk is not notified, a loss of network connection will result if LocalTalk is the current network connection. Note that only LocalTalk implemented in AppleTalk version 57 or later recognizes the Speed Change Transition event. Contact Apple Software Licensing for licensing AppleTalk version 57.
  1369. Regarding LocalTalk on the Macintosh Plus, the timing values are hard-coded in ROM regardless of the CPU speed. Vendors of accelerators for Macintosh Plus computers should contact DTS for information on how to make LocalTalk work for you.
  1370. The ATTransSpeedChange Transition
  1371. From Assembly language, the stack upon calling looks as follows:
  1372. ATQEvent    RECORD    0    
  1373. ReturnAddr    DS.L    1    ; address of caller
  1374. theEvent    DS.L    1    ; = 'sped'; ID of ATTransSpeedChange
  1375. aqe    DS.L    1    ; pointer to task record
  1376.         ENDR
  1377. To notify LocalTalk that a change in processor speed has taken place, use the ATEvent procedure. Pass ATTransSpeedChange as the event parameter and a nil pointer as the infoPtr parameter. This event must be issued only at system task time. The ATEvent procedure is implemented as a glue routine in MPW 3.2 or greater. The following line of code demonstrates notification of the ATTransSpeedChange event.
  1378.      ATEvent (ATTransSpeedChange, nil);
  1379. Sample Pascal Source to LAPMgrExists Function
  1380. It is important to check whether the LAP Manager exists before making LAP Manager calls like LAPAddATQ. The LAP Manager is implemented beginning with AppleTalk version 53. Rather than check the low-memory global LAPMgrPtr, it is preferable to check for its existence from a higher level. The following Pascal source demonstrates this technique:
  1381. FUNCTION GestaltAvailable: Boolean;
  1382. CONST
  1383.     _Gestalt = $A1AD;
  1384. BEGIN
  1385.     GestaltAvailable := TrapAvailable(_Gestalt);
  1386.     { TrapAvailable is documented in Inside Macintosh Volume VI, page 3-8 }
  1387. END;
  1388. FUNCTION AppleTalkVersion: Integer;
  1389. CONST
  1390.     versionRequested = 1; { version of SysEnvRec }
  1391. VAR
  1392.     refNum: INTEGER;
  1393.     world: SysEnvRec;
  1394.     attrib: LONGINT;
  1395. BEGIN
  1396.     AppleTalkVersion := 0;    { default to no AppleTalk }
  1397.     IF OpenDriver('.MPP', refNum) = noErr THEN    { open the AppleTalk driver }
  1398.         IF GestaltAvailable THEN
  1399.         BEGIN
  1400.             IF (Gestalt(gestaltAppleTalkVersion, attrib) = noErr) THEN
  1401.                 AppleTalkVersion := BAND(attrib, $000000FF);
  1402.         END
  1403.         ELSE    { Gestalt or gestaltAppleTalkVersion selector isn't available. }
  1404.             IF SysEnvirons(versionRequested, world) = noErr THEN
  1405.                 AppleTalkVersion := world.atDrvrVersNum;
  1406. END;
  1407. FUNCTION LAPMgrExists: Boolean;
  1408. BEGIN
  1409.     { AppleTalk phase 2 is in AppleTalk version 53 and later }
  1410.     LAPMgrExists := (AppleTalkVersion >= 53);
  1411. END;
  1412. Sample AppleTalk Transition Queue Function
  1413. A sample AppleTalk Transition Queue function has been implemented in both C and Pascal. These samples have been submitted as snippet code to appear on the Developer CD Series disc. Since Transition Queue handlers are called with a C-style stack frame, the Pascal sample includes the necessary C glue.
  1414. Sample AppleTalk Transition Queue Function in C
  1415. The following is a sample AppleTalk Transition Queue handler for C programmers. To place the handler in the AppleTalk Transition Queue, define a structure of type myATQEntry in the main body of the application. Assign the SampleTransQueue function to the myATQEntry.CallAddr field. Use the LAPAddATQFixed function to add the handler to the AppleTalk Transition Queue. Remember to remove the handler with the LAPRmvATQFixed function before quitting the application.
  1416. Warning:     The System 7 Tuner extension will not load AppleTalk resources if it detects that AppleTalk is off at boot time. Remember to check the result from the LAPAddATQFixed function to determine whether the handler was installed successfully. 
  1417. The following code was written with MPW C v3.2:
  1418. /*----------------------------------------------------------------------
  1419.   file: TransQueue.h
  1420. ----------------------------------------------------------------------*/
  1421.   
  1422. #include <AppleTalk.h>
  1423. /*
  1424.  *  Transition Queue routines are designed with C calling conventions in mind.
  1425.  *  They are passed parameters with a C-style stack and return values are expected
  1426.  *  to be in register D0.
  1427.  */
  1428. #define ATTransOpen            0    /* .MPP just opened */
  1429. #define ATTransClose            2    /* .MPP is closing */
  1430. #define ATTransClosePrep        3    /* OK for .MPP to close? */
  1431. #define ATTransCancelClose        4    /* .MPP close was canceled*/
  1432. #define ATTransNetworkTransition    5    /* .MPP Network ADEV transition */
  1433. #define ATTransNameChangeTellTask    6    /* Flagship name is changing */
  1434. #define ATTransNameChangeAskTask    7    /* OK to change Flagship name */
  1435. #define ATTransCancelNameChange    8    /* Flagship name change was canceled */
  1436. #define ATTransCableChange        'rnge'    /* Cable Range Change has occurred */
  1437. #define ATTransSpeedChange        'sped'    /* Change in processor speed has occurred                            */
  1438. /*----------------------------------------------------------------------
  1439.         NBP Name Change Info record
  1440. ----------------------------------------------------------------------*/
  1441. typedef struct NameChangeInfo {
  1442.     Str32     newObjStr;    /* new NBP name */
  1443.     Ptr    name;        /* Ptr to location to place a pointer to Pascal string                    of */
  1444.                 /* name of process that NAK'd the event */
  1445. }
  1446.     NameChangeInfo, *NameChangePtr, **NameChangeHdl;
  1447. /*----------------------------------------------------------------------
  1448.         Network Transition Info Record
  1449. ----------------------------------------------------------------------*/
  1450. typedef struct TNetworkTransition {
  1451.     Ptr        private;        /* pointer to private structure */
  1452.     ProcPtr    netValidProc;        /* pointer to network validation                                   procedure */
  1453.     Boolean     newConnectivity;    /* true = new connection */
  1454.                         /* false = loss of connection */
  1455. }
  1456.     TNetworkTransition , *TNetworkTransitionPtr, **TNetworkTransitionHdl;
  1457. typedef    pascal long    (*NetworkTransitionProcPtr)(TNetworkTransitionPtr netTrans, \
  1458.                       unsigned long theNet);
  1459. /*----------------------------------------------------------------------
  1460.         Cable Range Transition Info Record
  1461. ----------------------------------------------------------------------*/
  1462. typedef struct TNewCRTrans {
  1463.     short    newCableLo;    /* the new Cable Lo received from RTMP */
  1464.     short    newCableHi;    /* the new Cable Hi received from RTMP */
  1465. }
  1466.     TNewCRTrans , *TNewCRTransPtr, **TNewCRTransHdl;
  1467. /*----------------------------------------------------------------------
  1468.         AppleTalk Transition Queue Element
  1469. ----------------------------------------------------------------------*/
  1470. typedef struct    myATQEntry {
  1471.     Ptr        qLink;        /* -> next queue element */
  1472.     short        qType;        /* unused */
  1473.     ProcPtr    CallAddr;    /* -> transition procedure */
  1474.     Ptr        globs;        /* -> to user defined globals */
  1475. }
  1476.     myATQEntry, *myATQEntryPtr, **myATQEntryHdl;
  1477. /*----------------------------------------------------------------------
  1478.   file: TransQueue.c
  1479. ----------------------------------------------------------------------*/
  1480. #include <Memory.h>
  1481. #include <AppleTalk.h>
  1482. #include "TransQueue.h"
  1483. long SampleTransQueue(long selector, myATQEntry *q, void *p)
  1484. {
  1485.     long            returnVal = 0; /* return 0 for unrecognized events */
  1486.     NameChangePtr                myNameChangePtr;
  1487.     TNewCRTransPtr            myTNewCRTransPtr;
  1488.       TNetworkTransitionPtr        myTNetworkTransitionPtr;
  1489.     NetworkTransitionProcPtr        myNTProcPtr;
  1490.     StringPtr                newNamePtr;
  1491.     long                    checkThisNet;
  1492.     char                     **t;
  1493.     short                    myCableLo, myCableHi;
  1494.         
  1495.     /*
  1496.      * This is the dispatch part of the routine. We'll check the selector passed        into the task; its location is 4 bytes off the stack (selector).
  1497.      */
  1498.     switch(selector) {
  1499.         case ATTransOpen:
  1500.             /*
  1501.              *  Someone has opened the .MPP driver. This is where one would              * reset the application to its usual network state (that is,              * you could register your NBP name here). Always return 0.
  1502.              */
  1503.             break;
  1504.             
  1505.         case ATTransClose:
  1506.             /*
  1507.              *  When this routine is called, .MPP is going to shut down no              *  matter what we do. Handle that type of situation here (that              *  is, one could remove an NBP name and close down all                  *  sessions); 'p' will be nil. Return 0 to indicate no error.
  1508.              */
  1509.             break;
  1510.             
  1511.         case ATTransClosePrep:
  1512.             /* 
  1513.              *  This event gives us the chance to deny the closing of              *  AppleTalk if we want. Returning    a value of 0 means it's OK              *  to close; nonzero indicates we'd rather not close at this              *  time.
  1514.              *
  1515.              *  With this event, the parameter 'p' actually means                  *  something. 'p' in this event is a pointer to an address              *  that can hold a pointer to a string of our choosing. This              *  string indicates to the user which task would rather not              *  close. If you don't want AppleTalk to close, but you don't              *  have a name to stick in there, you MUST place a nil value              *  in there instead.
  1516.              *
  1517.              *  (We're doing this all locally to this case because it's C              *   and we can, so there.)
  1518.              */
  1519.             newNamePtr = (StringPtr)NewPtr(sizeof(Str32));
  1520.             
  1521.             /*
  1522.              *  Assume Ptr allocation successful.
  1523.              */
  1524.             
  1525.             newNamePtr = "\pBanana Mail";    /* This will either be an             Ax reference or PC relative depending on compiler and options.             */
  1526.              
  1527.             /* 
  1528.              *  Get a new reference to the address we were passed (in a              *  form we can use). 
  1529.              */
  1530.             t = (char **) p;
  1531.             /* 
  1532.              *  Place the address of our string into the address we were              *  passed. 
  1533.              */
  1534.             *t = (char *)newNamePtr;
  1535.             /* 
  1536.              *  Return a nonzero value so that AppleTalk knows we'd rather              *  not close.
  1537.              */
  1538.             returnVal = 1;
  1539.             break;                 
  1540.             
  1541.         case ATTransCancelClose:
  1542.             /*
  1543.              *  Just kidding, we didn't really want to cancel that                  *  AppleTalk closing after all. Reset all your network                  *  activities that you have disabled here (if any). In our              *  case, we'll just fall through. 'p' will be nil. 
  1544.                 */
  1545.             break;
  1546.             
  1547.         case ATTransNetworkTransition:
  1548.             /*
  1549.              *  A Remote AppleTalk connection has been made or broken. 
  1550.              *  'p' is a pointer to a TNetworkTransition record.
  1551.              *  Always return 0.
  1552.              */
  1553.             myTNetworkTransitionPtr = (TNetworkTransitionPtr)p;
  1554.             /*
  1555.              *  Check newConnectivity element to determine whether
  1556.              *  Remote Access is coming up or going down.
  1557.              */
  1558.             if (myTNetworkTransitionPtr->newConnectivity) {
  1559.                 /*
  1560.                  * Have a new connection
  1561.                  */
  1562.             }
  1563.             else {
  1564.                 /*
  1565.                  * Determine which network addresses need to be                      * validated and assign the value to checkThisNet.
  1566.                    */
  1567.                 checkThisNet = 0x1234FD80;  /* network 0x1234, node                 0xFD, socket 0x80 */
  1568.                 myNTProcPtr = (NetworkTransitionProcPtr)myTNetworkTransitionPtr->netValidProc;
  1569.                 if ((*myNTProcPtr)(myTNetworkTransitionPtr,                     checkThisNet)) {
  1570.                     /* 
  1571.                      * Network is still valid.
  1572.                      */
  1573.                 }
  1574.                 else {
  1575.                     /* 
  1576.                      * Network is no longer valid.
  1577.                      */
  1578.                 }
  1579.             }
  1580.             break;
  1581.             
  1582.         case ATTransNameChangeTellTask:
  1583.             /*
  1584.              *  Someone is changing the Flagship name and there is nothing              *  we can do. The parameter 'p' is a pointer to a Pascal-style              *  string that holds the new Flagship name. */
  1585.             newNamePtr = (StringPtr) p;
  1586.             /*
  1587.              *  You should deregister any previously registered NBP entries              *  under the 'old' Flagship name. Always return 0.*/
  1588.             break;
  1589.             
  1590.         case ATTransNameChangeAskTask:
  1591.             /*
  1592.              *  Someone is messing with the Flagship name. 
  1593.              *  With this event, the parameter 'p' actually means                  *  something. 'p' is a pointer to a NameChangeInfo record. The              *  newObjStr field contains the new Flagship name. Try to              *  register a new entity using the new Flagship name.                  *  Returning a value of 0 means it's OK to change the Flagship              *  name.
  1594.              */
  1595.             myNameChangePtr = (NameChangePtr)p;
  1596.             /*
  1597.              *  If the NBPRegister is unsuccessful, return the error. You              *  must also set p->name pointer with a pointer to a Pascal-             *  style string of the process name. */
  1598.             break;
  1599.             
  1600.         case ATTransCancelNameChange:
  1601.             /*
  1602.              *  Just kidding, we didn't really want to change that name              *  after all. Remove new NBP entry registered under the              *  ATTransNameChangeAskTask Transition. In our case,  we'll              *  just fall through. 'p' will be nil. Remember to return 0.                 */
  1603.             break;
  1604.         case ATTransCableChange:
  1605.             /*
  1606.              *  The cable range for the network has changed. The pointer              *  'p' points to a structure with the new network range.              *  (TNewCRTransPtr)p->newCableLo the lowest value of the new              *  network range. (TNewCRTransPtr)p->newCableHi is the highest              *  value of the new network range. After handling this event,              *  always return 0. */
  1607.             myTNewCRTransPtr = (TNewCRTransPtr)p;
  1608.             myCableLo = myTNewCRTransPtr->newCableLo;
  1609.             myCableHi = myTNewCRTransPtr->newCableHi;
  1610.             break;
  1611.         case ATTransSpeedChange:
  1612.             /*
  1613.              *  The processor speed has changed. Only LocalTalk responds to              *  this event. We demonstrate this event for completeness              *  only. Always return 0. */
  1614.             break;
  1615.         default:
  1616.             /*
  1617.              *  For future Transition Queue events (and yes, Virginia,              *  there will be more). */
  1618.             break;
  1619.     } /* end of switch */
  1620.     
  1621.     /* 
  1622.      *    return value in register D0 
  1623.      */
  1624.     return returnVal;
  1625. }
  1626. Sample AppleTalk Transition Queue Function in Pascal
  1627. The following is a sample AppleTalk Transition Queue handler for Pascal programmers. AppleTalk Transition Queue handlers are passed parameters using the C parameter passing convention. In addition, the 4-byte function result must be returned in register D0. To meet this requirement, a C procedure is used to call the handler, then to place the 4-byte result into register D0. The stub procedure listing follows the handler. 
  1628. To place the handler in the AppleTalk Transition Queue, define a structure of type myATQEntry in the main body of the application. Assign the CallTransQueue C procedure to the myATQEntry.CallAddr field. Use the LAPAddATQFixed function to add the handler to the AppleTalk Transition Queue. Remember to remove the handler with the LAPRmvATQFixed function before quitting the application.
  1629. Warning: The System 7 Tuner extension will not load AppleTalk resources if it detects that AppleTalk is off at boot time. Remember to check the result from the LAPAddATQFixed function to determine whether the handler was installed successfully. 
  1630. The following code was written with MPW Pascal and C v3.2:
  1631. {********************************************************************************
  1632.   file: TransQueue.p
  1633. ********************************************************************************}
  1634. UNIT TransQueue;
  1635. INTERFACE
  1636. USES MemTypes, QuickDraw, OSIntF, AppleTalk;
  1637. CONST
  1638. (*  Comment the following 4 constants since they are already defined in the AppleTalk unit. 
  1639.     ATTransOpen                 =   0;  { .MPP is opening }
  1640.     ATTransClose                =   2;  { .MPP is closing }
  1641.     ATTransClosePrep            =   3;  { OK for .MPP to close? }
  1642.     ATTransCancelClose          =   4;  { .MPP close was canceled }
  1643. *)
  1644.     ATTransNetworkTransition    =   5;  { .MPP Network ADEV transition }
  1645.     ATTransNameChangeTellTask   =   6;  { Flagship name is changing }
  1646.     ATTransNameChangeAskTask    =   7;  { OK to change Flagship name }
  1647.     ATTransCancelNameChange     =   8;  { Flagship name change was canceled. }
  1648.     ATTransCableChange          =   'rnge'; { Cable Range Change has occurred. }
  1649.     ATTransSpeedChange          =   'sped'; { Change in processor speed has                                occurred. }
  1650. {----------------------------------------------------------------------
  1651.         NBP Name Change Info record
  1652. ----------------------------------------------------------------------}
  1653. TYPE    
  1654. NameChangeInfo = RECORD
  1655.     newObjStr    : Str32;        { new NBP name }
  1656.     name        : Ptr;            { Ptr to location to place a pointer to                           Pascal string of }
  1657.                                 { name of process that                                   NAK'd the event }
  1658.     END;
  1659. NameChangePtr = ^NameChangeInfo;
  1660. NameChangeHdl = ^NameChangePtr;
  1661. {----------------------------------------------------------------------
  1662.         Network Transition Info Record
  1663. ----------------------------------------------------------------------}
  1664. TNetworkTransition = RECORD
  1665.     private        : Ptr;            { pointer to private structure }
  1666.     netValidProc    : ProcPtr;    { pointer to network validation procedure }
  1667.     newConnectivity : Boolean;    { true = new connection, }
  1668.                              { false = loss of connection }
  1669.     END;
  1670. TNetworkTransitionPtr = ^TNetworkTransition;
  1671. TNetworkTransitionHdl = ^TNetworkTransitionPtr;
  1672. { The netValidProc procedure has the following C interface. Note the }
  1673. { CallNetValidProc C function, which follows. The C Glue routine allows the Pascal }
  1674. { handler to make the call to the netValidProc function. }
  1675. {
  1676. typedef pascal long    (*NetworkTransitionProcPtr)(TNetworkTransitionPtr netTrans, \
  1677.                       unsigned long theNet);
  1678. }
  1679. {----------------------------------------------------------------------
  1680.         Cable Range Transition Info Record
  1681. ----------------------------------------------------------------------}
  1682. TNewCRTrans = RECORD
  1683.     newCableLo    : INTEGER;    { the new Cable Lo received from RTMP }
  1684.     newCableHi    : INTEGER;    { the new Cable Hi received from RTMP }
  1685.     END;
  1686. TNewCRTransPtr = ^TNewCRTrans;
  1687. TNewCRTransHdl = ^TNewCRTransPtr;
  1688.    
  1689. {----------------------------------------------------------------------
  1690.         AppleTalk Transition Queue Element
  1691. ----------------------------------------------------------------------}
  1692. myATQEntry = RECORD
  1693.     qlink        : Ptr;            { -> next queue element }
  1694.     qType        : INTEGER;    { unused }
  1695.     CallAddr    : ProcPtr;    { -> transition procedure }
  1696.     globs        : Ptr;        { -> to user defined globals }
  1697.     END;
  1698. myATQEntryPtr = ^myATQEntry;
  1699. myATQEntryHdl = ^myATQEntryPtr;
  1700. {---------------- Prototypes --------------------}
  1701. FUNCTION SampleTransQueue (selector :LONGINT; q :myATQEntryPtr;  p :Ptr) : LONGINT;
  1702. {
  1703.  *  Transition Queue routines are designed with C calling conventions in mind.
  1704.  *  They are passed parameters with a C-style stack and return values are expected
  1705.  *  to be in register D0. Note that the CallTransQueue C glue routine is used
  1706.  *  to reverse the C-style stack to Pascal style before calling the handler. The
  1707.  *  procedure CallTransQueue follows this listing. To install this Trans Queue
  1708.  *  handler, assign CallTransQueue to the CallAddr field, NOT SampleTransQueue.
  1709.  }
  1710. FUNCTION CallNetValidProc(p : ProcPtr; netTrans : TNetworkTransitionPtr; 
  1711.                              theNet : LONGINT) : LONGINT; 
  1712. {
  1713.  *  CallNetValidProc is used to call the netValidProc passed in the 
  1714.  *  TNetworkTransition record. Since Pascal cannot call the ProcPtr directly, a C 
  1715.  *  glue routine is used. This routine is defined following this listing.
  1716.  }
  1717. IMPLEMENTATION
  1718. FUNCTION SampleTransQueue (selector :LONGINT; q :myATQEntryPtr;  p :Ptr) : LONGINT;
  1719. VAR
  1720.     returnVal            : LONGINT;
  1721.     myNameChgPtr            : NameChangePtr;
  1722.     myTNewCRTransPtr        : TNewCRTransPtr;
  1723.     myTNetworkTransitionPtr    : TNetworkTransitionPtr;
  1724.     newNamePtr            : StringPtr;
  1725.     processNameHdl        : StringHandle;
  1726.     myCableLo, myCableHi        : INTEGER;
  1727.     shortSelector            : INTEGER;
  1728.     checkThisNet                
  1729. BEGIN
  1730.     returnVal := 0;             { return 0 for unrecognized events )
  1731.     {
  1732.      *  This is the dispatch part of the routine. We'll check the selector passed      *  into the task; its location is 4 bytes off the stack (selector).
  1733.      }
  1734.     IF ((selector <= ATTransCancelNameChange) AND (selector >= ATTransOpen)) THEN
  1735.     {
  1736.      *  Check whether a numeric selector is being used whose known values are      *  between 8 and 0 so that we can implement a CASE statement with an INTEGER      *  var.
  1737.      }
  1738.     BEGIN
  1739.         shortSelector := selector;
  1740.         CASE shortSelector OF
  1741.             ATTransOpen:
  1742.             BEGIN
  1743.                 {
  1744.                  *  Someone has opened the .MPP driver. This is where                  *  one would reset the application to its usual                      *  network state (that is, you could register your NBP                  *  name here). Always return 0.
  1745.                  }
  1746.             END;
  1747.                 
  1748.             ATTransClose:
  1749.             BEGIN
  1750.                 {
  1751.                  *  When this routine is called, .MPP is going to shut                  *  down no matter what we do. Handle that type of                  *  situation here (that is, one could remove an NBP                  *  name and close down all sessions). 'p' will be nil.                  *  Return 0 to indicate no error.
  1752.                  }
  1753.             END;
  1754.                 
  1755.             ATTransClosePrep:
  1756.             BEGIN
  1757.                 {
  1758.                  *  This event gives us the chance to deny the closing                  *  of AppleTalk IF we want. Returning a value of 0                  *  means it's OK to close; nonzero indicates we'd                  *  rather not close at this time.*
  1759.                  *  With this event, the parameter 'p' actually means                  *  something. 'p' in this event is a pointer to an                  *  address that can hold a pointer to a string of our                  *  choosing. This string indicates to the user which                  *  task would rather not close. If you don't want                  *  AppleTalk to close, but you don't have a name to                  *  stick in there,  you MUST place a nil value in                  *  there instead.
  1760.                  }
  1761.     
  1762.                 { 
  1763.                  *  Get a new reference to the address we were passed                  *  (in a form we can use).
  1764.                  *  (We're doing this all locally to this case because                  *  we can, so there.)
  1765.                  }
  1766.                 processNameHdl := StringHandle(NewHandle(sizeof(Str32))); 
  1767.                 
  1768.                 {
  1769.                  *  Place the address of our string into the address we                  *  were passed. 
  1770.                  }
  1771.                  := 'Banana Mail';
  1772.                 Ptr(p) := Ptr(processNameHdl);
  1773.                 
  1774.                 {
  1775.                  *  Return a nonzero value so that AppleTalk knows we'd                  *  rather not close.
  1776.                  }
  1777.                 returnVal := 1;
  1778.             END;
  1779.             ATTransCancelClose:
  1780.             BEGIN
  1781.                 {
  1782.                  *  Just kidding, we didn't really want to cancel that                  *  AppleTalk closing after all. Reset all your network                  *  activities that you have disabled here (IF any). In                  *  our case, we'll just fall through. 'p' will be nil. 
  1783.                  }
  1784.             END;
  1785.             ATTransNetworkTransition:
  1786.             BEGIN
  1787.                 {
  1788.                  *  A Remote AppleTalk connection has been made or                  *  broken. 'p' is a pointer to a TNetworkTransition                  *  record. Always return 0.
  1789.                  }
  1790.                 myTNetworkTransitionPtr := TNetworkTransitionPtr(p);
  1791.                 {
  1792.                  *  Check newConnectivity element to determine whether
  1793.                  *  Remote Access is coming up or going down.
  1794.                  }
  1795.                 if (myTNetworkTransitionPtr^.newConnectivity) THEN 
  1796.                 BEGIN
  1797.                     {
  1798.                      * Have a new connection.
  1799.                      }
  1800.                 END
  1801.                 ELSE 
  1802.                 BEGIN
  1803.                     {
  1804.                      * Determine which network addresses need to be                      *  validated and assign the value to                          *  checkThisNet.
  1805.                      }
  1806.                     checkThisNet = $1234FD80;  /* network $1234,                     node $FD, socket $80 */
  1807.                     if (CallNetValidProc(myTNetworkTransitionPtr^.netValidProc,
  1808.                             myTNetworkTransitionPtr,                                 checkThisNet) <> 0) THEN
  1809.                     BEGIN
  1810.                         {
  1811.                          * Network is still valid.
  1812.                          }
  1813.                     END
  1814.                     ELSE
  1815.                     BEGIN
  1816.                         {
  1817.                          * Network is no longer valid.
  1818.                          }
  1819.                     END;
  1820.                 END;
  1821.             END;
  1822.             ATTransNameChangeTellTask:
  1823.             BEGIN
  1824.                 {
  1825.                  *  Someone is changing the Flagship name and there is                  *  nothing we can do. The parameter 'p' is a pointer                  *  to a Pascal-style string that holds the new                      *  Flagship name.
  1826.                 }
  1827.                 newNamePtr := StringPtr (p);
  1828.                 {
  1829.                  *  You should deregister any previously registered NBP                  *  entries under the 'old' Flagship name. Always                  *  return 0.
  1830.                  }
  1831.             END;
  1832.             ATTransNameChangeAskTask:
  1833.             BEGIN
  1834.                 { 
  1835.                  *  Someone is messing with the Flagship name.
  1836.                  *  With this event, the parameter 'p' actually means                  *  something. 'p' is a pointer to a NameChangeInfo                  *  record. The newObjStr field contains the new                      *  Flagship name. Try to register a new entity using                  *  the new Flagship name. Returning a value of 0 means                  *  it's OK to change the Flagship name.
  1837.                  }
  1838.                 myNameChgPtr := NameChangePtr (p);
  1839.                 {  
  1840.                  *  If the NBPRegister is unsuccessful, return the                  *  error. You must also set p->name pointer with a                  *  pointer to a string of the process name.
  1841.                  }
  1842.             END;
  1843.             ATTransCancelNameChange:
  1844.             BEGIN
  1845.                 {
  1846.                  *  Just kidding, we didn't really want to cancel that                  *  name change after all. Remove new NBP entry                      *  registered under the  ATTransNameChangeAskTask                  *  Transition. 'p' will be nil. Remember to return 0. 
  1847.                  }
  1848.             END;
  1849.             OTHERWISE
  1850.                 returnVal := 0;
  1851.                 {
  1852.                  *  Just in case some other numeric selector is                      *  implemented.
  1853.                  }
  1854.         END; { CASE }
  1855.     END
  1856.     ELSE IF (ResType(selector) = ATTransCableChange) THEN
  1857.     BEGIN
  1858.         {
  1859.          *  The cable range for the network has changed. The pointer 'p'          *  points to a structure with the new network range.                  *  (TNewCRTransPtr)p->newCableLo is the lowest value of the new          *  network range. (TNewCRTransPtr)p->newCableHi is the highest value          * of the new network range. After handling this event, always return          *  0.
  1860.          }
  1861.         myTNewCRTransPtr := TNewCRTransPtr(p);
  1862.         myCableLo := myTNewCRTransPtr^.newCableLo;
  1863.         myCableHi := myTNewCRTransPtr^.newCableHi;
  1864.         returnVal := 0;
  1865.     END
  1866.     ELSE IF (ResType(selector) = ATTransSpeedChange) THEN
  1867.     BEGIN
  1868.         {
  1869.          *  The processor speed has changed. Only LocalTalk responds to this          *  event. We demonstrate this event for completeness only. Always          *  return 0. 
  1870.          }
  1871.          returnVal := 0;
  1872.     END; { IF }
  1873.     SampleTransQueue := returnVal;
  1874. END;
  1875. FUNCTION CallNetValidProc(p : ProcPtr; netTrans : TNetworkTransitionPtr; 
  1876.                              theNet : LONGINT) : LONGINT; EXTERNAL;
  1877. END. { of UNIT }
  1878. /********************************************************************************
  1879.   file: CGlue.c
  1880. ********************************************************************************/
  1881. #include <AppleTalk.h>
  1882. /*----------------------------------------------------------------------
  1883.         Network Transition Info Record
  1884. ----------------------------------------------------------------------*/
  1885. typedef struct TNetworkTransition {
  1886.     Ptr        private;        /* pointer to private structure */
  1887.     ProcPtr    netValidProc;        /* pointer to network validation                                procedure */
  1888.     Boolean    newConnectivity;    /* true = new connection, */
  1889.                         /* false = loss of connection */
  1890. }
  1891.     TNetworkTransition , *TNetworkTransitionPtr, **TNetworkTransitionHdl;
  1892. typedef    pascal long    (*NetworkTransitionProcPtr)(TNetworkTransitionPtr netTrans, \
  1893.                       unsigned long theNet);
  1894. /*----------------------------------------------------------------------
  1895.         AppleTalk Transition Queue Element
  1896. ----------------------------------------------------------------------*/
  1897. typedef struct    myATQEntry {
  1898.     Ptr        qLink;        /* -> next queue element */
  1899.     short        qType;        /* unused */
  1900.     ProcPtr    CallAddr;    /* -> transition procedure */
  1901.     Ptr        globs;        /* -> to user defined globals */
  1902. }
  1903.     myATQEntry, *myATQEntryPtr, **myATQEntryHdl;
  1904. /*----------------------------------------------------------------------
  1905.         Prototypes
  1906. ----------------------------------------------------------------------*/
  1907. pascal long  SampleTransQueue (long selector, myATQEntry *q, void *p);
  1908. long CALLTRANSQUEUE(long selector, myATQEntry *q, void *p);
  1909. /* Capitalize CALLTRANSQUEUE so that linker can match this entry with */
  1910. /* the Pascal call. */
  1911. pascal long CallNetValidProc(ProcPtr p, TNetworkTransitionPtr netTrans, long theNet);
  1912. long CALLTRANSQUEUE(long selector, myATQEntry *q, void *p)
  1913. /* CallTransQueue sets up the Pascal stack for the SampleTransQueue handler, */
  1914. /* then puts the result into D0. */
  1915. {
  1916.     return(SampleTransQueue(selector, q, p));
  1917. }
  1918. pascal long CallNetValidProc(ProcPtr p, TNetworkTransitionPtr netTrans, long theNet)
  1919. /* CallNetValidProc is used to call the netValidProc pointed to by ProcPtr p. */
  1920. {
  1921.     NetworkTransitionProcPtr    myNTProcPtr;
  1922.     myNTProcPtr = (NetworkTransitionProcPtr)p;
  1923.     return ((*myNTProcPtr)(netTrans, theNet));
  1924. }
  1925. Multivendor ADEV Architecture
  1926. With the release of AppleTalk version 56, Apple implemented the Multivendor ADEV Architecture. Under the original architecture with versions of AppleTalk prior to 56, using EtherTalk or TokenTalk on Macintosh II class machines permitted only one brand of NuBus card where multiple Ethernet or token ring connections were desired. Furthermore, there was no support for a configuration of a NuBus slot device and a “slotless” device, such as a SCSI Ethernet connection.
  1927. As Ethernet comes built in on next-generation CPUs, this clearly presents a problem for customers wishing to mix Ethernet controller brands on the same CPU. The Multivendor Architecture presents a common interface through which basic AppleTalk services are provided. The new architecture simplifies software development whereas AppleTalk engineering provides the ADEV file, and the developer provides the hardware level driver software for Ethernet and token ring. By following the new architecture, Ethernet and token ring hardware cards will be compatible as new services are provided by AppleTalk (for example, AppleTalk Remote Access and MacTCP). 
  1928. AppleTalk version 56 and later is compatible with system software version 6.0.5 unless specifically stated otherwise in the release notes. 
  1929. Original Limitations
  1930. The original product allowed only one type of NuBus Ethernet or token ring controller or one “slotless” controller. This Multivendor ADEV Architecture deals only with the restriction of differing NuBus controllers. It does not address the mutual exclusion of slot and slotless devices, nor does it address the singularity of slotless devices.
  1931. NuBus slot Ethernet or token ring controller hardware is recognized by the original product through a series of Slot Manager SNextTypesRsrc calls. Any NuBus device that is in the network category and has a type classification of Ethernet /token ring is considered a NuBus slot controller device. Whenever such a device is found in a NuBus slot, the user can select it as the current AppleTalk network connection, or it can be used as a port in an Internet Router configuration.
  1932. When the AppleTalk network system uses this connection, an _Open, IMMED trap call is made with an ioNamePtr -> “.ENET/.TOKN”, and the ioSlot field set to the slot containing the card. Since only one driver resource can be installed in the system with this name, only one type of Ethernet or token ring card was supported under the original architecture.
  1933. ENET Driver Shell
  1934. System software version 7.0 and later (and Network Software Installers (NSI) system software version 1.1 and later) is packaged with the .ENET driver shell that will support multiple NuBus Ethernet controllers. The sole function of this driver is to locate the appropriate driver resource for the particular device selected, and transfer control to the open routine for that driver. It accomplishes this in the following fashion:
  1935. • Obtains the Board ID from the board sResource information for the given slot.
  1936. • For the driver shell installed using NSI version 1.2.4 or later, the shell searches for resources of type 'enet' with the ID equal to the Board ID in the System file and in the System ROM, and for a driver in the slot resources in the ROM of the slot device. It uses the word (2 bytes) immediately following the DRVR name to determine which driver is the most recent; higher values are newer versions. If no driver is found, an open error is returned.
  1937.     For the driver shell installed prior to NSI version 1.2.4, the shell uses _GetResource to obtain a resource of type 'enet' with the ID equal to the Board ID from the system file. If the resource is present, proceeds to use it as the driver code resource as defined below, otherwise attempts to load the driver from the slot resources in the ROM of the slot device. If neither code resource is found, returns an open error.
  1938. • Detaches the newly loaded resource.
  1939. • Modifies the device control entry for the current _Open call with information from the loaded driver code (address to the driver).
  1940. • Obtains the address of the open routine from the driver header information.
  1941. • JSRs to the open routine of the loaded driver.
  1942. • If the open is successful, returns, otherwise recovers the handle for the loaded driver and disposes of it.
  1943. This very simple technique allows developers to quickly repackage driver resources by simply changing the resource type and ID.
  1944. Built-in Ethernet on newer CPUs makes use of the board sResource list for slot zero, which should be present on all CPUs. These systems also have the Ethernet device sResource lists, and also have the .ENET driver in the sResources as well.
  1945. The Easy Install process supplied on the Network Software Installer version 1.1 and later, and on the system software installers for 7.0 and later, install the driver shell when it recognizes that an Apple EtherTalk NB or Ethernet NB (or other Ethernet board with Board ID 8) is installed in the system. 
  1946. .TOKN Driver Shell
  1947. The .TOKN driver shell is currently available from Apple Software Licensing (SW.LICENSE) for licensing. The driver and Multivendor TokenTalk ADEV are being packaged beginning with system software version 7.0.1 and AppleTalk products that require AppleTalk version 57 or later. The operation of the .TOKN driver shell is similar to the .ENET driver shell. In place of searching for and loading the 'enet' resource, a 'tokn' resource will be used instead. The new driver will affect all developers whose .TOKN drivers get replaced by the driver shell.
  1948. .TOKN Driver Basics
  1949. The following guidelines describe the minimum requirements for developers of token ring products for the Macintosh to be compatible with the TokenTalk Phase 2 driver software. MacDTS strongly recommends that all developers of token ring products implement the basic functionality described below. By following these guidelines, the product will be compatible with AppleTalk Remote Access, MacTCP, and future releases of AppleTalk and related products.
  1950. The .TOKN driver is similar to the structure of the .ENET driver as described in Appendix B, “Macintosh Ethernet Driver Details” in the Macintosh AppleTalk Connections Programmer’s Guide (Final Draft 2, November 11, 1989) and more recently in Inside Macintosh Volume VI, page 32-88. These documents describe the expected functionality of the .ENET driver. The .TOKN driver interface that you design can be a superset of the functionality discussed here. The following are some additional guidelines and exceptions to consider:
  1951. •    The driver can obtain the slot number from the DCE entry dCtlSlot.
  1952. •    The driver need only support EAttach protocol type 0. Return an error on other protocol types.
  1953. •    Implement the add and delete functional address in place of the EAddMulti and EDelMulti commands.
  1954. •    Implement the ESetGeneral call to return a result of noErr.
  1955. •    Implement source routing support if the driver is to support the source routing bridges.
  1956. • On EWrite call:
  1957.     The first buffer in the WDS contains a 802.3 MAC header (6-byte destination address + 6-byte source address + 2-byte length field). The 6-byte destination address is the only important field to the driver. The source address and the length fields are not used for token ring media. The header is 14 bytes in length.
  1958.     The second buffer in the WDS contains the LLC header and the SNAP header. This buffer is 8 bytes in length.
  1959.     The remainder of the WDS is the user data.
  1960.     The packet that gets put out on the “wire” will not include the 2-byte length field. The packet header will have the 6-byte destination address, followed by the 6-byte source address, followed by the LLC and SNAP header, and the user data. 
  1961. • On Receive:
  1962.     Define a Read Header Area (RHA) into which to create the 14 byte 802.3 MAC header. Read the header into the RHA and set A3 to point to the end of the RHA; place the 6-byte destination and source addresses into the first 12 bytes of the RHA. From the hardware, get the length of the packet and place it into the last 2 bytes of the RHA. This step is necessary as the LAP Manager is designed to handle and Ethernet style packet.
  1963.     Calculate the packet length (LLC header + SNAP header + data). Place the length in register D1.W. Also place the computed length into the length field of the 802.3 MAC header (this length does not include the source routing and 802.5 fields). Place the address of the ReadPacket routine into register A4. Disable the interrupt. Call the protocol handler or use DeferUserFn as described below. Enable the interrupt.
  1964.     As A0 is reserved for use by the driver, it could be used to point to the next byte to be read by the driver, for the ReadPacket and ReadRest functions.
  1965. • Other Notes:
  1966. If the protocol handler calls your ReadRest routine with a buffer too small to hold the entire remaining packet, set the Z-bit in the CCR before returning. Clearing the Z-bit indicates that the ReadRest routine handled the packet successfully.
  1967. Driver Considerations for Virtual Memory
  1968. With the release of system software version 7.0 and the virtual memory option, it is critical for driver software to protect against the possibility of a double page fault. Since driver software runs at interrupt time, a non-virtual memory compatible packet processing routine could cause a page fault while the Macintosh is already processing a page fault. To protect against this possibility, the DeferUserFn is provided to allow interrupt service routines to defer code, which might cause a page fault, until a safe time. The following guidelines will help make your driver code compatible with virtual memory.
  1969. • In the Open routine, use Gestalt to test for the presence of virtual memory, and whether it’s on. If so, set a flag in your dctlstorage that you can reference later.
  1970. • If virtual memory is enabled, always use DeferUserFn to defer the delivery of your packet data to your clients. This is necessary to protect against page faults at interrupt time when your client reads data into her own (probably unlocked) memory. In addition, do not touch any memory that is not locked down (in the virtual memory sense, not the Memory Manager sense) while processing your interrupts.
  1971. • Set the VMImmuneBit to keep the system from locking down memory (bit 0 at offset dCtlFlags + 1). If the VMImmuneBit isn’t set, the system locks the user’s parameter block. In contrast, the user’s buffers remain unlocked unless locked by the application. As a result, it is necessary to assume that the buffers are unlocked, and to use DeferUserFn accordingly. Having the system lock the parameter block results in a noticeable performance hit. The solution to this problem is to set the VMImmuneBit, and to be careful to “touch” the parameter block only when it is “safe” to do so. One time when it might be “unsafe” is in a completion routine. Therefore, use DeferUserFn .
  1972. The VMImmune bit is not currently found in the MPW headers. Add the following line somewhere at the beginning of your driver code:
  1973.  
  1974.       VMImmuneBit     EQU    0
  1975.  
  1976. Somewhere in the beginning of your code, assuming that the driver is now virtual memory-aware, add the following line:
  1977.  
  1978.       BSET  #VMImmuneBit,dCtlFlags+1(A1)    ; set the bit
  1979.  
  1980. Warning:     Do not assume that DeferUserFn will always successfully queue your packet-handling routine. Check the return result. Under specific situations, the Defer-Function Queue can become full. If the return result is cannotDeferErr exit the slot interrupt routine with a result of zero to indicate that the interrupt could not be serviced.
  1981.  
  1982. Limiting DeferUserFn Calls
  1983. Your interrupt service routine can reduce the number of calls to DeferUserFn depending on the Network Interface Controller (NIC) being used. With the SONIC and other NICs, incoming packets are queued. An ISR for such a NIC can be designed to process not only the packet that generated the interrupt, but also successive packets. As a result, the ISR can be designed to set a “deferred function” flag to indicate that the service routine has been queued, then process all packets that it finds in the card’s queue. When the service routine has completed, it can then reset the deferred function flag. If the ISR is reentered, it can check whether the deferred function flag is set. If so, simply exit with a nonzero result in register D0 to indicate that the packet was processed. 
  1984. Using this algorithm, it is important to reset the NIC’s interrupt service register each time the ISR determines that a packet will be processed by a previously deferred function. If the register is not cleared, the card will remain in a constant state of interrupt, and the deferred function will never get a chance to execute.
  1985. Implementing DeferUserFn
  1986. The question may arise as to where to implement the DeferUserFn The following approach is one possible suggestion for devices that are not able to empty the NIC’s packet RAM all at once, and which implement a circular buffer or linked buffer list. Define an entry point where the ISR begins processing the packet from the card. At this entry point, there may be some code to check whether a packet transmission is under way and to perform a cleanup. There may also be code here to check whether the buffer has become overrun and to reset the NIC according to manufacturer’s guidelines. The driver code would copy the header into the RHA (Read Header Area), identify the protocol handler and set up register A4 with a pointer to the ReadPacket routine, then call the handler. Upon completion, the ISR might check whether additional packets have been received, if applicable. A flowchart of the deferred function process is as follows:
  1987. myDeferedFunction()
  1988. {
  1989.     If transmit complete
  1990.         do final cleanup of packet transmission
  1991.  
  1992.     If buffer overrun
  1993.         Reset the NIC according to manufacturer's guidelines
  1994.  
  1995.     while(received packets are waiting in adapter ram)
  1996.     {
  1997.         process packet
  1998.         call protocol handler
  1999.     }
  2000. }
  2001. On entry to the ISR, see whether virtual memory is active by checking the flag set by the open routine. Perform whatever processing is necessary, then pass DeferUserFn, the entry point described above, if virtual memory is active. If virtual memory is inactive, branch to the entry point and process the packet.
  2002. SONIC-Based Ethernet Driver Software Interface Change
  2003. With the introduction of SONIC-based Ethernet controllers, a modification was implemented into the Ethernet driver software to return additional information available from the SONIC chip network statistics counters. This section describes the format of the information returned by an EGetInfo call when the current network connection is through an Ethernet NB Card, an Ethernet LC Card, or through the built-in Ethernet available on the Macintosh Quadra 700/900/950.
  2004. EGetInfo Changes
  2005. The EGetInfo call can return up to 60 additional bytes of new information making the maximum number of bytes returned 78. As with the Apple EtherTalk NB Card (Apple/3Com card), the first 6 bytes returned contain the card’s Ethernet address. The remaining bytes that are returned contain information different from that returned with the Apple EtherTalk NB Card.
  2006. The next 12 bytes (offset 6–17) returned contain NO information but are always returned zero filled for compatibility. The remaining 60 bytes returned contain SONIC chip network statistic counters. The counters are listed below in the following table with the decimal and hexadecimal offsets given from the start of the return buffer. Note that the offset of the first item in the return buffer, the Ethernet address, is at offset 0.
  2007. Byte offset:(start at 0)     Description
  2008. 18    ($12)       -     Frames transmitted OK
  2009. 22    ($16)       -     Single collision frames
  2010.                   26    ($1A)       -     Multiple collision frames
  2011.                   30    ($1E)       -     Collision frames
  2012.                   34    ($22)       -     Frames with deferred transmission
  2013.                   38    ($26)       -     Late collision
  2014.                   42    ($2A)       -     Excessive collisions
  2015.                   46    ($2E)       -     Excessive deferrals
  2016.                   50    ($32)       -     Internal MAC transmit error
  2017.                   54    ($36)       -     Frames received OK
  2018.                   58    ($3A)       -     Multicast frames received OK
  2019.                   62    ($3E)       -     Broadcast frames received OK
  2020.                   66    ($42)       -     Frame check sequence errors
  2021.                   70    ($46)       -     Alignment errors
  2022.                   74    ($4A)       -     Frames lost due to internal MAC 
  2023.                                                   receive error
  2024. With the release of AppleTalk version 58, a minor change was implemented into the EGetInfo call such that the number of bytes filled in by the call, is returned in the eDataSize field. The re-vised parameter block description for the .ENET driver supplied with AppleTalk version 58 is:
  2025. Distinguishing Apple’s SONIC-Based Ethernet Systems
  2026. When making the EGetInfo call, it is important to pass the correct size buffer. The control call will only fill in the buffer with the number of bytes specified in the eBuffSize field. Unless it is already known that the active Ethernet card is the Apple (3Com) EtherTalk NB Card, it is recommended that you pass a buffer large enough to accommodate the additional information returned by the driver for the SONIC chip. One method to distinguish the Apple (3Com) EtherTalk NB Card from Apple’s SONIC-based systems, is to fill the 78-byte buffer with a byte pattern like 0xFF. For the Apple EtherTalk NB Card, the last 60 bytes of the buffer will still be filled with the byte pattern. For Apple’s SONIC-based systems, the last 60 bytes of the buffer will not all contain the byte pattern. 
  2027. With the Ethernet driver released under AppleTalk version 58, an alternate method to distinguishing the two Apple Ethernet hardware cards is to pass in a pointer to a 78-byte buffer in the ePointer field, then to check the EDataSize value for the number of bytes filled into the buffer. For the original EtherTalk NB card, the number of returned bytes is 18; for the Ethernet NB card, the number of returned bytes will be 78.
  2028. Correction to the ENET.h Header File
  2029. Programs written for compilation with MPW C, which use the ENET.h header file supplied with MPW version 3.2.x are alerted to the fact the following declaration is incorrect. Users of Think C should check their ENET.h header file for the same error, as the version 5.0.x product was shipped with the header files supplied by the MPW team. This problem does not affect the corresponding Pascal interface file.
  2030. typedef struct {
  2031.       EParamHeader
  2032.       EParamMisc1 EParms1;
  2033.       char eMultiAddr[5];                 /*Multicast Address*/
  2034. }EParamMisc2;
  2035. The correct declaration has the eMultiAddr field immediately following the EParamHeader structure and the character array allocated 6 instead of 5 bytes as follows:
  2036. typedef struct {
  2037.       EParamHeader
  2038.       char eMultiAddr[6];                 /*Multicast Address*/
  2039. }EParamMisc2;
  2040. The EParamMisc2 structure applies only to the EAddMulti and EDelMulti control calls to the Ethernet, token ring and FDDI drivers. If you are using these calls, you might include a revised structure declaration in your source code file so that you need not worry about overwriting the corrected header file when supplied with a new version of MPW. The declaration would be as follows:
  2041. #include <ENET.h>
  2042. .
  2043. .
  2044. /* The following structure declaration replaces the incorrect EParamMisc2 
  2045.  * structure declaration presented in the ENET.h files supplied with MPW 
  2046.  * to v3.2.4 and possibly greater.
  2047.  */
  2048. typedef struct {
  2049.       EParamHeader
  2050.       char eMultiAddr[6];                 /*Multicast Address*/
  2051. }EParamMultiCast;
  2052. AppleTalk Multiple Node Architecture
  2053. Supporting multiple node addresses on a single machine connected to AppleTalk is a feature that has been created to support software applications such as AppleTalk Remote Access. Its implementation is general enough to be used by other applications as well.
  2054. Note:    AppleTalk version 57 or later is required to support the AppleTalk Multiple Node Architecture. Version 57 is compatible with system software version 6.0.5 and later. If you implement multinode functionality into your program you should also plan to include AppleTalk version 57 with your product. Contact Apple’s Software Licensing department (see end of this Note) for information on licensing AppleTalk.
  2055. What Is It?
  2056. Multiple Node AppleTalk provides network node addresses that are in addition to the normal (user node) DDP address assigned when AppleTalk is opened. These additional addresses have different characteristics from those of the user node address. They are not connected to the protocol stack above the data link layer. When an application acquires a multinode, the application has to supply a receive routine through which AppleTalk will deliver broadcasts and packets directed to that multinode address.
  2057. The number of multinode addresses that can be supported on one single machine is determined by a static limit imposed by the AppleTalk ADEV itself (for example, EtherTalk). The limit is currently 253 nodes for Apple’s implementation of EtherTalk ($0, $FF, and $FE being invalid node addresses) and 254 for LocalTalk ($0 and $FF being invalid node addresses). The number of receive routines that .MPP supports is determined by the static limit of 256. If all of the multiple nodes acquired need to have unique receive routines, then only a maximum of 256 nodes can be acquired, even if the ADEV provides support for more than 256 nodes. .MPP will support the lesser of either the maximum of 256 receive routines, or the node limit imposed by the ADEV.
  2058. Outbound DDP packets can be created with a user-specified source network, node, and socket (normally equal to a multinode address) with the new Network Write call. With this capability and the packet reception rules described above, a single machine can effectively become several nodes on a network. The user node continues to function as it always has.
  2059. Glue Code for Multinode Control Calls
  2060. The following files are provided for C and Pascal programmers to implement the new multinode calls presented in this Tech Note. First, for C programmers:
  2061. /*----------------------------------------------------------------------
  2062.   file: MultiNode.c
  2063. ----------------------------------------------------------------------*/
  2064. #include <Types.h>
  2065. #include <Devices.h>
  2066. #include <OSUtils.h>
  2067. #include <AppleTalk.h>
  2068. enum {
  2069. /*  MultiNode .MPP csCodes */
  2070.     netWrite = 261,                 /* Send packet through multinode */
  2071.     addNode = 262,                  /* Request a multinode */
  2072.     removeNode = 263,               /* Remove multinode */
  2073. };
  2074. typedef struct {
  2075.     MPPATPHeader
  2076.     char filler1;
  2077.     unsigned char checkSumFlag;     /* perform checksum on datagram */
  2078.     Ptr wdsPointer;                 /* Ptr to write-data structure */
  2079.     char filler2[2];
  2080.     union {
  2081.         AddrBlock reqNodeAddr;      /* preferred address requested */
  2082.         AddrBlock nodeAddr;         /* node address to be deleted */
  2083.         } MNaddrs;
  2084.     AddrBlock actNodeAddr;          /* actual node address acquired */
  2085.     Ptr recvRoutine;                /* address of packet receive routine */
  2086.     short reqCableLo;               /* preferred network range for the */
  2087.     short reqCableHi;               /*  node being acquired */
  2088.     char reserved[70];
  2089. } MNParamBlock;
  2090. typedef MNParamBlock*MNParmBlkPtr;
  2091. #ifdef __cplusplus
  2092. extern "C" {
  2093. #endif
  2094. pascal OSErr MNAddNode(MNParmBlkPtr thePBptr,Boolean async); 
  2095. pascal OSErr MNRemoveNode(MNParmBlkPtr thePBptr,Boolean async); 
  2096. pascal OSErr MNNetWrite(MNParmBlkPtr thePBptr,Boolean async); 
  2097. #ifdef __cplusplus
  2098. }
  2099. #endif
  2100. pascal OSErr MNAddNode(MNParmBlkPtr thePBptr,Boolean async)
  2101. {
  2102.     thePBptr->csCode = addNode;
  2103.     thePBptr->ioRefNum = mppUnitNum;
  2104.     return (PBControl((ParmBlkPtr)thePBptr, async));
  2105. }
  2106. pascal OSErr MNRemoveNode(MNParmBlkPtr thePBptr,Boolean async) 
  2107. {
  2108.     thePBptr->csCode = removeNode;
  2109.     thePBptr->ioRefNum = mppUnitNum;
  2110.     return (PBControl((ParmBlkPtr)thePBptr, async));
  2111. }
  2112. pascal OSErr MNNetWrite(MNParmBlkPtr thePBptr,Boolean async)
  2113. {
  2114.     thePBptr->csCode = netWrite;
  2115.     thePBptr->ioRefNum = mppUnitNum;
  2116.     return (PBControl((ParmBlkPtr)thePBptr, async));
  2117. }
  2118. Now for Pascal programmers:
  2119. UNIT MultiNode;
  2120. INTERFACE
  2121. USES
  2122.     MemTypes, QuickDraw, OSIntf, AppleTalk;
  2123. CONST
  2124. {    MultiNode .MPP csCodes }
  2125.     netWrite = 261;                 { Send packet through multinode }
  2126.     addNode = 262;                  { Request a multinode }
  2127.     removeNode = 263;               { Remove multinode }
  2128. TYPE
  2129. MNParmType = (AddNodeParm,RemoveNodeParm);
  2130. MNParamBlock = PACKED RECORD
  2131.     qLink: QElemPtr;                  {next queue entry}
  2132.     qType: INTEGER;                   {queue type}
  2133.     ioTrap: INTEGER;                  {routine trap}
  2134.     ioCmdAddr: Ptr;                   {routine address}
  2135.     ioCompletion: ProcPtr;            {completion routine}
  2136.     ioResult: OSErr;                  {result code}
  2137.     ioNamePtr: StringPtr;             {->filename}
  2138.     ioVRefNum: INTEGER;               {volume reference or drive number}
  2139.     ioRefNum: INTEGER;                {driver reference number}
  2140.     csCode: INTEGER;                  {call command code AUTOMATICALLY set}
  2141.     filler1: Byte;
  2142.     checkSumFlag: Byte;            { perform checksum on datagram }
  2143.     wdsPointer: Ptr;               { Ptr to write-data structure }
  2144.     filler2: INTEGER;
  2145.     CASE MNParmType of
  2146.       AddNodeParm:
  2147.        (reqNodeAddr: AddrBlock;    { preferred address requested }
  2148.            actNodeAddr: AddrBlock;    { actual node address acquired }
  2149.            recvRoutine: ProcPtr;      { address of packet receive routine }
  2150.            reqCableLo: INTEGER;       { preferred network range for the }
  2151.            reqCableHi: INTEGER;       {  node being acquired }
  2152.            reserved: PACKED ARRAY [1..70] of Byte);
  2153.       RemoveNodeParm:
  2154.         (nodeAddr: AddrBlock);  { node address to be deleted }
  2155.     END;
  2156. MNParmBlkPtr = ^MNParamBlock;
  2157. FUNCTION MNAddNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;
  2158. FUNCTION MNRemoveNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;
  2159. FUNCTION MNNetWrite(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;
  2160. IMPLEMENTATION
  2161. FUNCTION MNAddNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;
  2162. BEGIN
  2163.     thePBptr^.csCode := addNode;
  2164.     thePBptr^.ioRefNum := mppUnitNum;
  2165.     MNAddNode := PBControl(ParmBlkPtr(thePBptr), async);
  2166. END;
  2167. FUNCTION MNRemoveNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;
  2168. BEGIN
  2169.     thePBptr^.csCode := removeNode;
  2170.     thePBptr^.ioRefNum := mppUnitNum;
  2171.     MNRemoveNode := PBControl(ParmBlkPtr(thePBptr), async);
  2172. END;
  2173. FUNCTION MNNetWrite(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;
  2174. BEGIN
  2175.     thePBptr^.csCode := netWrite;
  2176.     thePBptr^.ioRefNum := mppUnitNum;
  2177.     MNNetWrite := PBControl(ParmBlkPtr(thePBptr), async);
  2178. END;
  2179. END.
  2180. Things You Need to Know When Writing a Multinode Application
  2181. Two new .MPP driver control calls have been added to allow multinode applications to add and remove multinodes.
  2182. AddNode (csCode=262)
  2183. A user can request an extra node using a control call to the .MPP driver after it has opened. Only one node is acquired through each call.
  2184. Parameter Block:
  2185.     -->    24    ioRefNum    short        ; driver ref. number
  2186.     -->    26    csCode    short        ; always = AddNode (262)
  2187.     -->    36    reqNodeAddr    AddrBlock    ; the preferred address requested 
  2188.                                 ; by the user.
  2189.     <--    40    actNodeAddr    AddrBlock    ; actual node address acquired.
  2190.     -->    44    recvRoutine    long        ; address of the receive routine                                 ; for MPP to call during packet                                 ; delivery.
  2191.     -->    48    reqCableLo    short        ; the preferred range        
  2192.     -->    50    reqCableHi    short        ; node being acquired.
  2193.     -->    52    reserved[70]    char        ; 70 reserved bytes
  2194. AddrBlock:
  2195.     aNet            short                ; network #
  2196.     aNode        unsigned chae            ; node #
  2197.     aSocket    unsigned char            ; should be zero for this call.
  2198. The AddNode call must be made as an IMMEDIATE control call at system task time. The .MPP driver will try to acquire the requested node address. The result code will be returned in the ioResult field in the parameter block. The result code –1021 indicates that the .MPP driver was unable to continue with the AddNode call because of the current state of .MPP. The caller should retry the AddNode call (the retry can be issued immediately after the AddNode call failed with error–1021) until a node address is successfully attained or another error is returned.
  2199. If the requested node address is zero, invalid, or already taken by another machine on the network, a random node address will be generated by the .MPP driver. The parameters reqCableLo and reqCableHi will be used only if there is no router on the network and all the node addresses in the network number specified in NetHint (the last used network number stored in parameter RAM) are taken up.
  2200. In this case, the .MPP driver tries to acquire a node address from the network range as specified by reqCableLo and reqCableHi. The network range is defined by the seed router on a network. If a specific cable range is not important to the application, set the reqCableLo and reqCableHi fields to zero. The recvRoutine is an address of a routine in the application to receive broadcasts and directed packets for the corresponding multinode.
  2201. Possible Error Codes:
  2202.     noErr    0        ; success
  2203.     tryAddNodeAgainErr -1021        ; MPP was not able to add node,                 ; try again.
  2204.     MNNotSupported    -1022        ; Multinode is not supported by
  2205.                 ; the current ADEV.
  2206.     noMoreMultiNodes    -1023        ; no node address is available on                 ; the network.
  2207. RemoveNode (csCode=263)
  2208. This call removes a multinode address and must be made at system task time. Removal of the user node is not allowed.
  2209. Parameter Block:
  2210. -->    24    ioRefNum    word        ; driver ref. number
  2211. -->    26    csCode    word        ; always = RemoveNode (263)
  2212. -->    36    NodeAddr    AddrBlock    ; node address to be deleted.
  2213. Possible Error Codes:
  2214. noErr    0        ; success
  2215. paramErr    -50        ; bad parameter passed
  2216. Receiving Packets 
  2217. Broadcast packets are delivered to both the user’s node and the multinodes on every machine. If several multinodes are acquired with the same recvRoutine address, the recvRoutine, listening for these multinodes, will be called only once in the case of a broadcast packet.
  2218. Multinode receive handlers should determine the number of bytes already read into the Read Header Area (RHA) by subtracting the beginning address of the RHA from the value in A3 (see Inside Macintosh Volume II, page 326, for a description of the Read Header Area). A3 points past the last byte read in the RHA. The offset of RHA from the top of the .MPP variables is defined by the equate ToRHA in the MPW include file ATalkEqu.a. The receive handler is expected to call ReadRest to read in the rest of the packet. In the case of LocalTalk, ReadRest should be done as soon as possible to avoid loss of the packet. Register A4 contains the pointer to the ReadPacket and ReadRest routines in the ADEV.
  2219. To read in the rest of the packet,
  2220.         JSR    2(A4)
  2221. On entry:
  2222.     A3    pointer to a buffer to hold the bytes
  2223.     D3    size of the buffer (word), which can be zero to throw away packet
  2224. On exit:
  2225.     D0    modified
  2226.     D1    modified
  2227.     D2    preserved
  2228.     D3    Equals zero if requested number of bytes was read; is less than zero if packet         was –D3 bytes too large to fit in buffer and was truncated; is greater than zero if         D3 bytes were not read (packet is smaller 
  2229.         than buffer)
  2230.     A0    preserved
  2231.     A1    preserved
  2232.     A2    preserved
  2233.     A3    pointer to 1 byte after the last byte read
  2234. For more information about ReadPacket and ReadRest, refer to Inside Macintosh Volume II, page 327.
  2235.     
  2236. A user can determine if a link is extended by using the GetAppleTalkInfo control call. The Configuration field returned by this call is a 32-bit word that describes the AppleTalk configuration. Bit number 15 (0 is LSB) is on if the link in use is extended. Refer to Inside Macintosh Volume VI, page 32-15.
  2237. Sending Datagrams Through Multinodes
  2238. To send packets through multinodes, use the new .MPP control call, NetWrite. NetWrite allows the owner of the multinode to specify a source network, node, and socket from which to send a datagram.
  2239. NetWrite (csCode=261)
  2240. Parameter Block:
  2241.     -->    26    csCode    word    ; always NetWrite (261)
  2242.     -->    29    checkSumFlag    byte    ; checksum flag
  2243.     -->    30    wdsPointer    pointer    ; write data structure
  2244. Possible Error Codes:
  2245.     noErr        0        ; success
  2246.     ddpLenErr    -92        ; datagram length too big
  2247.     noBridgeErr    -93        ; no router found
  2248.     excessCollsns    -95        ; excessive collisions on write
  2249. This call is very similar to the WriteDDP call. The key differences are as follows:
  2250. •    The source socket is not specified in the parameter block. Instead it is specified along with the source network number and source node address in the DDP header pointed to by the write-data structure (WDS). Furthermore, the socket need not be opened. Refer to Inside Macintosh Volume II, page 310, for a description of the write-data structure. It is important to note that the caller needs to fill in the WDS with the source network, source node, and source socket values. .MPP does not set these values for the NetWrite call. 
  2251. •    The checkSumFlag field has a slightly different meaning. If true (nonzero), then the checksum for the datagram will be calculated prior to transmission and placed into the DDP header of the packet. If false (zero), then the checksum field is left alone in the DDP header portion of the packet. Thus if a checksum is already present, it is passed along unmodified. For example, the AppleTalk Remote Access program sets this field to zero, since remote packets that it passes to the .MPP driver already have valid checksum fields. Finally, if the application desires no checksum, the checksum field in the DDP header in the WDS header must be set to zero.
  2252. Datagrams sent with this call are always sent using a long DDP header. Refer to Inside AppleTalk, second edition, page 4-16, for a description of the DDP header. Even if the destination node is on the same LocalTalk network, a long DDP datagram is used so that the source information can be specified. The LAP header source node field will always be equal to the user node address (sysLapAddr), regardless of the source node address in the DDP header.
  2253. AppleTalk Remote Access Network Number Remapping
  2254. Network applications should be careful not to pass network numbers as data in a network transaction. AppleTalk Remote Access performs limited network number remapping. If network numbers are passed as data, they will not get remapped. AppleTalk Remote Access recognizes network numbers in the DDP header and among the various standard protocol packets, NBP, ZIP, RTMP, and so on.
  2255. Is There a Router on the Network?
  2256. Do not assume that there are no routers on the network if your network number is zero. With AppleTalk Remote Access, you can be on network zero and be connected to a remote network. Network applications should use the GetZoneList or the GetBridgeAddress calls to determine if there is a router on the network.
  2257. New for AppleTalk ADEVs 
  2258. First, a word from our sponsors: The information in this section is provided to assist ADEV developers in updating their products for compatibility with AppleTalk Remote Access. If you are a Ethernet or token ring developer, MacDTS strongly urges that you consider following the Multivendor ADEV Architecture described earlier. For developers of Fiber Data Distribution Interface (FDDI) network interface cards, please contact Apple Software Licensing for information on licensing the new FDDI Phase 2 ADEV and Driver shell. 
  2259. Several new calls have been implemented into the .MPP driver for AppleTalk version 57. Two calls, AOpen and AClose, were built into AppleTalk version 54 and later, and are also documented here. These calls notified the ADEV of changes in the status of the .MPP driver. For AppleTalk version 57, three new calls, AAddNode, ADelNode, and AGetNodeRef, plus a change to the AGetInfo call, were implemented to support the Multiple Node Architecture.
  2260. With the release of AppleTalk version 58, support is provided for the Simple Network Management Protocol (SNMP), and for the new Router Manager product. Programmer’s Guides for each of these products are available from APDA. For all ADEVs, an important change is required for the Router Manager product to provide basic SNMP support. An ADEV must be modified to support a minor change in the AGetInfo call. The ADEV must respond to the AGetInfo call by returning the slot number of the network device being supported, in the second reserved byte. This change is required so that when queried by a console, the Router Manager can report the slot number of the connection being supported. For those network devices running via the LocalTalk ports, the second reserved byte should continue to return zero. There is no support for such ADEVs at this time.
  2261. EtherTalk Phase 2, version 2.3, and TokenTalk phase 2, version 2.4, drivers support the new Multiple Node Architecture. Both drivers and AppleTalk version 57 are available through the Network Software Installer, version 1.1. As mentioned previously, AppleTalk version 57 and these drivers are compatible with system software version 6.0.5 and later. Note that the AppleTalk Remote Access product includes the EtherTalk Phase 2, version 2.3 driver, but not the multinode-compatible TokenTalk Phase 2, version 2.4, driver. Token ring developers, who license TokenTalk Phase 2, version 2.2 and earlier, should contact Apple’s Software Licensing department.
  2262. The following information describes changes to the ADEV that are required for multinode compatibility. This information is of specific importance to developers of custom ADEVs. The ADEV can be expected to function under version 6.0.5 and later. A version 3 ADEV must be used with AppleTalk version 57 or later. Developers of custom ADEVs will want to contact Software Licensing to license AppleTalk version 57.
  2263. For compatibility with Multinode AppleTalk, the 'atlk' resource of an ADEV must be modified to respond to these calls as described below. To determine whether an ADEV is multinode compatible, the .MPP driver makes an AGetInfo call to determine whether the ADEV version is 3 or later. Any ADEVs responding with a version of 3 or later must be prepared to respond to the new calls: AAddNode, ADelNode, and AGetNodeRef. See the Macintosh AppleTalk Connections Programmer’s Guide for more information about writing an AppleTalk ADEV.
  2264. The desired architecture for a multinode-compatible ADEV is such that it delivers incoming packets to the LAP Manager along with an address reference number, AddrRefNum. The LAP Manager uses the AddrRefNum to locate the correct receive routine to process the packet. For broadcast packets, the LAP Manager handles multiple deliveries of the packet to each multinode receive routine.
  2265. The .MPP driver for AppleTalk version 57 supports the new control call to add and remove multinodes, along with the network write call that allows the specification of the source address. .MPP includes a modification in its write function to check for one multinode sending to another. .MPP supports intermultinode transmission within the same machine. For example, the user node may want to send a packet to a multinode within the same system.
  2266. AGetInfo (D0=3)
  2267. The AGetInfo call should be modified to return the maximum number of AppleTalk nodes that can be provided by the atlk. This limit will be used by .MPP to control the number of multinodes that can be added on a single machine. The new interface is as follows:
  2268. Call:        D1 (word)    length (in bytes) of reply buffer
  2269.         A1 ->         Pointer to GetInfo record buffer
  2270. Return:    A1 ->        Pointer to GetInfo record
  2271.         D0        nonzero if error (buffer is too small)
  2272.     AGetInfoRec = RECORD
  2273. <--    version:        INTEGER;    { version of ADEV, set to three (3) }
  2274. <--    length:        INTEGER;    { length of this record in bytes }
  2275. <--    speed:            LongInt;    { speed of link in bits/sec }
  2276. <--    BandWidth:        Byte;        { link speed weight factor }
  2277. <--    reserved:        Byte;        { set to zero }
  2278. <--    slot:                   Byte;        { device slot number or zero for 
  2279.                         ( LocalTalk ports }
  2280. <--    reserved:        Byte;        { set to zero }
  2281. <--    flags:            Byte;        { see below }
  2282. <--    linkAddrSize:        Byte;        { of link addr in bytes }
  2283. <--    linkAddress:        ARRAY[0..5] OF Byte;
  2284. <--    maxnodes:         INTEGER;
  2285.     END;
  2286.     flags:    bit 7 = 1 if this is an extended AppleTalk, else 0
  2287.         bit 6 = 1 if the link is used for a router-only connection (reserved
  2288.             for half-routing)
  2289.         bit 5 through 0 reserved, = 0
  2290. maxnodes is the total number of nodes (user node and multinodes) the ADEV supports. If a version 3 ADEV does not support multinodes, it must return 0 or 1 in the maxnodes field in AGetInfoRec and the ADEV will not be called to acquire multinodes. The version 3 ADEV will be called by .MPP in one of the following two ways to acquire the user node:
  2291. • If the ADEV returns a value of 0 in maxnodes, .MPP will issue Lap Write calls to the ADEV with D0 set to $FF indicating that ENQs should be sent to acquire the user node. .MPP is responsible for retries of ENQs to make sure no other nodes on the network already have this address. This was the method .MPP used to acquire the user node before multinodes were introduced. This method of sending ENQs must be available, even though the new AAddNode call is provided, to allow older versions of AppleTalk to function properly with a version 3 ADEV.
  2292. • If the ADEV returns a value of 1 in maxnodes, the new AAddNode function will be called by .MPP to acquire the user node.
  2293. For values of maxnode greater than 1, the new AAddNode function will be called by .MPP to acquire the additional multinodes.
  2294. AAddNode (D0=9)
  2295. This is a new call that is used to request the acquisition of an AppleTalk node address. It is called by the .MPP driver during the execution of the AddNode control call mentioned earlier. The ADEV is responsible for retrying enough ENQs to make sure no other nodes on the network already have the address. .MPP makes this call only during system task time.
  2296. Call:         A0->        Pointer to parameter block
  2297. Return:     D0         = zero if address was acquired successfully
  2298.                 ≠ zero if no more addresses can be acquired
  2299.     atlkPBRec        Record    csParam
  2300. -->    NetAddr        DS.L    1    ; offset 0x1C  24-bit node address to                         ; acquire
  2301. -->    NumTrys        DS.W    1    ; offset 0x20  # of tries for address
  2302. -->    DRVRPtr        DS.L    1    ; offset 0x22  ptr to .MPP vars
  2303. -->    PortUsePtr        DS.L    1    ; offset 0x26  ptr to port use byte
  2304. -->    AddrRefNum        DS.W    1    ; offset 0x2A  address ref number used                         ; by .MPP
  2305.     EndR
  2306. The offset values describe the location of the fields from the beginning of the parameter block pointed to by A0. atlkPBRec is the standard parameter block record header for a _Control call. The field NetAddr is the 24-bit AppleTalk node address that should be acquired. The node number is in the least significant byte 0 of NetAddr. The network number is in bytes 1 and 2 of NetAddr; byte 3 is unused. NumTrys is the number of tries the atlk should send AARP probes on non-LocalTalk networks to verify that the address is not in use by another entity. On LocalTalk networks, NumTrys x 32 number of ENQs will be sent to verify an address. 
  2307. DRVRPtr and PortUsePtr are normally passed when the atlk is called to perform a write function. For ADEVs that support multinodes, AppleTalk calls the new AAddNode function rather than the write function in the ADEV to send ENQs to acquire nodes. However, the values DRVRPtr and PortUsePtr are still required for the ADEV to function properly and are passed to the AAddNode call. AddrRefNum is a reference number passed in by .MPP. The ADEV must store each reference number with its corresponding multinode address. The use of the reference number is described in the following two sections.
  2308. For multinode-compatible ADEVs, .MPP issues the first AAddNode call to acquire the user node. The AddrRefNum associated with the user node must be 0xFFFF. It is important to assign 0xFFFF as the AddrRefNum of the user node, and to disregard the AddrRefNum passed by .MPP for the user node. See the discussion at the end of the ADelNode description.
  2309. ADelNode (D0=10)
  2310. This is a new call that is used to remove an AppleTalk node address. It can be called by the .MPP driver to process the RemoveNode control call mentioned earlier.
  2311. Call:        A0->    Pointer to parameter block
  2312.             NetAddr contains the node address to be deleted
  2313. Return:    D0         = zero if address is removed successfully
  2314.             ≠ zero if address does not exist
  2315.             atlkPBRec.AddrRefNum = AddrRefNum to be used by .MPP if             the operation is successful
  2316.     atlkPBRec    Record    csParam
  2317. -->    NetAddr    DS.L    1    ; offset 0x1C  24-bit node                     ; address to remove
  2318. <--    AddrRefNum    DS.W    1    ; offset 0x2A  AddrRefNum                     ; passed in by AAddNode
  2319.                     ; on return
  2320.         EndR
  2321. The field NetAddr is the 24-bit AppleTalk node address that should be removed. As with the AAddNode selector, the node number is in the least significant byte 0 of NetAddr. The network number is in bytes 1 and 2 of NetAddr; byte 3 is unused. The address reference number, AddrRefNum, associated with the NetAddr, must be returned to .MPP in order for .MPP to clean up its data structures for the removed node address.
  2322. As mentioned above, a value of 0xFFFF must be returned to .MPP after deleting the user node. When the AppleTalk connection is started up for the first time on an extended network, the ADEV can expect to process an AAddNode request followed shortly by an ADelNode request. This results from the implementation of the provisional node address for the purpose of talking with the router to determine the valid network number range to which the node is connected. After obtaining the network range, .MPP issues the ADelNode call to delete the provisional node. The next ADelNode call will be to acquire the unique node ID for the user node. As mentioned previously, .MPP can pass a value different from 0xFFFF for the user node. The user node is acquired before any multinode. The ADEV needs to keep track of the number of AAddNode and ADelNode calls issued to determine whether the user node is being acquired. Refer to Inside AppleTalk, second edition, page 4-8, for additional information.
  2323. AGetNodeRef (D0=11)
  2324. This is a new call that is used by .MPP to find out if a multinode address exists on the current ADEV. This call is currently used by .MPP to check if a write should be looped back to one of the other nodes on the machine (the packet does not actually need to be sent through the network) or should be sent to the ADEV for transmission.
  2325. Call:        A0->        Pointer to parameter block
  2326. Return:     D0->        = zero if address does not exist on this machine
  2327.                 ≠ zero if address exists on this machine
  2328.                 atlkPBRec.AddrRefNum = AddrRefNum (corresponding to                 the node address) if the operation is successful
  2329.     atlkPBRec    Record    csParam
  2330. -->    NetAddr    DS.L    1     ; offset 0x1C  24-bit node                          ; address to remove
  2331. <--    AddrRefNum    DS.W    1    ; offset 0x2A  AddrRefNum                         ; passed in by AAddNode
  2332.                     ; on return
  2333.         EndR
  2334. The field NetAddr is the 24-bit AppleTalk node address whose AddrRefNum is requested. The node number is in the least significant byte 0 of NetAddr. The network number is in bytes 1 and 2 of NetAddr; byte 3 is unused. The address reference number, AddrRefNum, associated with the NetAddr, must be returned to .MPP. Remember to return 0xFFFF as the AddrRefNum for the user node.
  2335. AOpen (D0=7)
  2336. Call:        
  2337.     -->    D4.B        current port number
  2338. ADEVs should expect the AOpen call whenever the .MPP driver is being opened. This is a good time for the ADEV to register multicast addresses with the link layer or register a Transition Queue handler. After this call is completed, .MPP is ready to receive packets. If the ADEV does not process this message, simply return, RTN with a ControlErr.
  2339. Note that AOpen is not specific to the Multinode Architecture.
  2340. AClose (D0=8)
  2341. AClose is called only when .MPP is being closed (for example, .MPP is closed when the “inactive” option is selected in the Chooser or when the user switches links in network cdev). The ADEV can use this event to deregister any multicast addresses with the link layer or remove an existing Transition Queue handler. After this AClose call is completed, the ADEV should not defend for any node addresses until .MPP reopens and acquires new node addresses. If the ADEV does not process this message, simply return, RTN with a ControlErr.
  2342. Note that AClose is not specific to the Multinode Architecture.
  2343. For comparison, descriptions of AInstall and AShutDown are documented as follows:
  2344. AInstall (D0=1)
  2345. Call:
  2346.     -->    D1.L =    value from PRAM (slot, ID, unused, atlk resource ID)
  2347.     <--    D1.L =    high 3 bytes for parameter RAM returned by the ADEV,                 if no error
  2348.     <--    D0.W =    error code
  2349.  
  2350. The AInstall call is made before .MPP is opened either during boot time or when the user switches links in network cdev. This call is made during system task time so that the ADEV is allowed to allocate memory, make file system calls, or load resources and so on. Note: AOpen call will be made during .MPP opens.
  2351. AShutDown (D0=2)
  2352. ADEVs should expect the AShutDown call to be made when the user switches links in the Network cdev. The network cdev closes .MPP, which causes the AClose call to be made before the cdev issues the AShutDown call. Note: the AShutDown call is always made during system task time; therefore, deleting memory, unloading resources, and file system calls can be done at this time.
  2353. Receiving Packets
  2354. The address reference number (AddrRefNum) associated with each node address must be passed to .MPP when delivering packets upward. When making the LAP Manager call LReadDispatch to deliver packets to AppleTalk, the ADEV must fill the high word of D2 in with the address reference number, corresponding to the packet’s destination address (LAP node address in the LocalTalk case and DDP address in the non-LocalTalk case). There are a few special cases:
  2355. • In the case of broadcasts and packets directed to the user node, $FFFF (word) should be used as the address reference number.
  2356. • On non-LocalTalk networks, packets with DDP destination addresses matching neither the user node address nor any of the multinode addresses should still be delivered to the LAP Manager so that the router can forward the packet on to the appropriate network. In this case, the high word of D2 should be filled in with the address reference number, $FFFE, to indicate to MPP that this packet is not for any of the nodes on the machine in the case of a router running on a machine on an extended network. 
  2357. • On LocalTalk networks, the ADEV looks only at the LAP address; therefore, if the LAP address is not the user node, one of the multinodes, or a broadcast, the packet should be thrown away.
  2358. Defending Multinode Addresses
  2359. Both LocalTalk (RTS and CTS) and non-LocalTalk (AARP) ADEVs have to be modified to defend not only for the user node address but also for any active multinode addresses.
  2360. Corrections/Clarifications to the LAP Manager
  2361. The interface for the Link Access Protocol (LAP) Manager is presented in the document Macintosh AppleTalk Connections Programmer’s Guide, available from APDA, p/n M7056/A. This section provides additional descriptions to the LAP Manager functions described in the Programmer’s Guide.
  2362. LRdDispatch (D0 = 1)
  2363. The LRdDispatch routine is called by an ADEV’s 'atlk' packet handling routine to notify the LAP Manager that a packet has been received, and to pass the packet to the LAP Manager for processing by the appropriate protocol handler. The documentation indicates that this routine “even though it is called with a JSR, does not return to the caller, but jumps to the protocol handler that is attached to the protocol indicated in (register) D2.” 
  2364. When called to handle LRdDispatch, the LAP Manager searches its protocol table for a match to the protocol specified in D2. If found, the return address placed on the stack by the JSR instruction is removed. For this reason, the caller will not be returned to if a protocol handler is found. This also means that the packet handling routine that calls LRdDispatch must restore the stack to the state the stack was in when the packet handler was entered.
  2365. LWrtInsert (D0 = 2)
  2366. The LWrtInsert description indicates that setting bit 6 of the flag byte in register D1, “does not disable the port B serial communications controller (SCC).…” This bit no longer has any meaning under AppleTalk. 
  2367. AppleTalk Version Information
  2368. The following table is presented to assist AppleTalk developers in understanding which versions of AppleTalk are required by the various AppleTalk products. This list does not identify the individual bug fixes associated with each release of AppleTalk.
  2369. AppleTalk Version    .MPP Version    .ATP Version    
  2370. Apple Products Using That Version    
  2371.                 
  2372. 19    19    19    Macintosh Plus ROM    
  2373. 48    48    46    Macintosh SE ROM    
  2374.             Macintosh Classic ROM    
  2375. 48.1    48    46    AppleShare File Server v1.0    
  2376. 49    49    49    Macintosh II ROM    
  2377.             Macintosh IIcx ROM    
  2378.             Macintosh SE/30    
  2379. 50    50    49    AppleShare File Server v1.1    
  2380. 51    51    51    AppleShare Print Server v2.0    
  2381. 52    52    52    AppleShare File Server v2.0    
  2382.             Macintosh IIx ROM    
  2383.             Macintosh IIci ROM    
  2384.             Macintosh Portable ROM    
  2385.             PowerBook 100 ROM    
  2386.                 
  2387.  
  2388. Phase 1 drivers
  2389. AppleTalk Version    .MPP Version    .ATP Version    
  2390. Apple Products Using That Version    
  2391. 53    53    53    AppleTalk Phase 2 products    
  2392.             AppleTalk Internet Router v2.0    
  2393.             Apple EtherTalk NB Card 2.0    
  2394.             Apple TokenTalk NB Card 2.0    
  2395. 54    54    54    Macintosh IIfx    
  2396.             Macintosh LC, LC II, & IIsi    
  2397. 55    55    55    Apple Ethernet LC Card (for Macintosh LC)    
  2398. 56    56    56    System 7.0, 7.0.1    
  2399.             Macintosh Classic II    
  2400.             PowerBook 140, 160, 170, 180    
  2401.             Macintosh Quadra 700, 900, 950    
  2402. 57.0.1    57.0.1    57.0.1    AppleTalk Remote Access    
  2403.             Apple TokenRing 4/16 NB Card    
  2404.             Apple Ethernet NB Card    
  2405. 57.0.3    57.0.3    57.0.3    Apple Ethernet LC Card (for Macintosh LC II)    
  2406. 57.0.4    57.0.4    57.0.4    MacTCP Token Ring Extension v1.0    
  2407.             System 7.1, MacTCP 1.1.1    
  2408.             Macintosh Duo 210, 230    
  2409.             Macintosh IIvi, IIvx    
  2410.             Macintosh Color Classic    
  2411.             Macintosh LC II    
  2412.             PowerBook 165c    
  2413.             Macintosh Quadra 800    
  2414.             Macintosh Centris 610, 650    
  2415. 58    58    58    Apple Internet Router v3.0    
  2416.             Mac SNMP    
  2417.  
  2418. Phase 2 drivers
  2419. Some interesting notes:
  2420. •     .MPP and .ATP driver versions weren’t always the same in versions of AppleTalk before version 51. The .MPP driver version is the AppleTalk version number.
  2421. •     The Phase 1 RAM-based drivers (versions 49 through 52) were supplied as file that could be drag-installed (that is, the installation consisted of dropping them into the System Folder).
  2422. •     The Phase 2 RAM-based drivers (versions 53 through 58) must be installed by an Installer script that will install the various system pieces (files, resources, and so on) needed to load and support these new drivers; these versions cannot be drag-installed.
  2423. •     AppleTalk version 56 or greater includes the .DSP driver (ADSP). Starting with version 56, the .DSP driver version is the same as the AppleTalk version.
  2424. Apple software products that require the Phase 2 RAM-based drivers must be installed using the Installer program. Apple supplies an Installer script that will copy all files and system resources needed. Apple licenses the source to an Installer script that you can use if you license AppleTalk to ship with your products.
  2425. Contacting Apple Software Licensing
  2426. Software Licensing can be reached as follows:
  2427.     Software Licensing
  2428.     Apple Computer, Inc.
  2429.     20525 Mariani Avenue, M/S 38-I
  2430.     Cupertino, CA 95014
  2431.     MCI: 312-5360
  2432.     AppleLink: SW.LICENSE
  2433.     Internet: SW.LICENSE@AppleLink.Apple.com
  2434.     (408)974-4667
  2435. Further Reference:
  2436. •    Inside AppleTalk, Second Edition, Addison-Wesley
  2437. •    Inside Macintosh, Volume II, The AppleTalk Manager, Addison-Wesley
  2438. •    Inside Macintosh, Volume V, The AppleTalk Manager, Addison-Wesley
  2439. •    Inside Macintosh, Volume VI, The AppleTalk Manager, Addison-Wesley
  2440. •    Macintosh AppleTalk Connections Programmer’s Guide, Final Draft 2, Apple Computer, Inc. (M7056/A)
  2441. •    AppleTalk Phase 2 Protocol Specification, Apple Computer, Inc. (C0144LL/A)
  2442. •    AppleTalk Remote Access Developer’s Toolkit, Apple Computer, Inc. (R0128LL/A)
  2443. •    M.NW.AppleTalk2Mac
  2444. NuBus is a trademark of Texas Instruments.
  2445. NW 14 - AppleTalk Timers Explained
  2446. Networking    
  2447. Written by:    Sriram Subramanian & Pete Helme    April 1990
  2448. This Technical Note explains how to effectively use timers and retry mechanisms of the various AppleTalk protocols to achieve maximum performance on an internet.
  2449. The most fundamental service in an AppleTalk internet is the Datagram Delivery Protocol (DDP), which provides a best-effort, connectionless, packet delivery system.  A sequence of packets sent using DDP on an AppleTalk internet between a pair of machines may traverse a single high-speed Ethernet network or it may wind across multiple intermediate data links such as LocalTalk, TokenRing, etc., which are connected by routers.  Some packet loss is always inevitable because of the loosely coupled nature of the underlying networks.  Even on a single high-speed Ethernet network, packets can be lost due to collisions or a busy destination node.  The AppleTalk Transaction Protocol (ATP), the AppleTalk Data Stream Protocol (ADSP), and other high-level protocols protect against packet loss and ensure reliability by using positive acknowledgement with  packet retransmission mechanism.
  2450. The basic transaction process in ATP consists of a client in a requesting node sending a Transaction Request (TReq) packet to a client in a responding node.  The client in the responding node is expected to service the request and generate a series of Transaction Response (TResp) packets, which also serves as an acknowledgement.  The ATP process in the requesting node also starts a timer when it sends a packet and retransmits a packet if the timer expires before a complete response arrives.  In a large internet with multiple gateways, it is impossible to know how quickly acknowledgements may return to the requestor.  If you set the retry time to be too small, you may be retransmitting a request while a delayed response is en route, but if you wait too long to retransmit a request, application performance may suffer.  More importantly, the delay at each gateway depends upon the traffic, so the time required to transmit a packet and receive an acknowledgement varies from one instant to another.  To further complicate matters, two packets sent back to back could take completely different routes to the destination.
  2451. Selecting ATP Retry Time And Retry Count
  2452. You can use the round trip time for a transaction as a heuristic for setting the retry time and retry count.  The round trip time between two nodes in a particular internet at a particular time is usually deterministic.
  2453. The easiest way to set the retry time is to assign a static value based on the round trip time for a transaction.  The AppleTalk Echo Protocol (AEP) can be used to obtain the round trip time in a given moment between two nodes.  AEP is implemented in each node as a DDP client residing on statically-assigned socket number four.  You should use DDP to send AEP requests through any socket that is available, and you should use the maximum packet size that you plan on using in your application.  You can listen for AEP responses by implementing a socket listener.  The following code is an example AEP socket listener.
  2454. ;_________________________________________________________________________
  2455. ;_________________________________________________________________________
  2456. ;
  2457. ; EchoDude
  2458. ;
  2459. ; 3/90 pvh - MacDTS
  2460. ;
  2461. ; ©1990 Apple Computer, Inc.
  2462. ; The following MPW Asm code is a socket listener for reading in returned Echo 
  2463. ; (DDP type 4) packets.  
  2464. ;
  2465. ; The target device was shipped a packet with a '1' in the first byte of the data 
  2466. ; area by way of a DDPWrite.  It was sent to socket 4, the Echoer socket.  If the
  2467. ; target device has an Echoer, it will send a return packet to us of equal size 
  2468. ; except it will have replaced the '1' in the first byte with the value '2'.  This 
  2469. ; indicates an EchoReply packet.
  2470. ;
  2471. ; The listener itself (RcvEcho) is added with a POpenSkt (Inside Mac V-513) call by 
  2472. ; passing the address of the listener in the listener field of the parameter block.
  2473. ;
  2474. ; All we really are trying to accomplish here is to set up a notification for 
  2475. ; returned packets from the target Echoer.  A time (Ticks) is stuffed into a
  2476. ; location our app can find (actually back into the packet buffer) and will be used 
  2477. ; to calculate round trips times.  We'll also save off the hop count from the packet
  2478. ; header for fun too since I have nothing better to do with my time on weekends.
  2479. ;
  2480. ; More could be done with this listener as far as making sure that we are only 
  2481. ; receiving back a packet from the node we sent it to etc.... but we can't 
  2482. ; encompass everything in a sample.  Okay, well we could… but we have to leave 
  2483. ; something for you guys to do.
  2484. ;
  2485. ; It should be noted that careful preservation of register A5 is necessary. 
  2486. ; LAP requires that A5 be preserved AFTER the call to ReadRest. i.e. you
  2487. ; cannot save A5 onto the stack when your socket listener is entered, call ReadRest
  2488. ; and then restore A5 from the stack and exit.  Wah.  LAP requires that the address
  2489. ; placed in A5 during ReadRest be there when your socket listener is exited.
  2490. ; So… if you need a different A5 after the call to ReadRest make sure you restore 
  2491. ; it before RTS-ing back the caller.
  2492. ;
  2493. ;
  2494. ;    Called:
  2495. ;         A0,A1,D1 : Preserve until after ReadRest
  2496. ;         A2 -> MPP local variables
  2497. ;         A3 -> RHA after DDP header
  2498. ;         A4 -> ReadPacket, 2(A4) -> ReadRest
  2499. ;         A5 Useable until ReadRest
  2500. ;         A6,D4-D7 : Preserve across call
  2501. ;
  2502. ;__________________________________________________________________________
  2503. EchoSkt    EQU    4        ; Echo socket number
  2504. EP         EQU    4        ; EP DDP protocol type
  2505. EPReq      EQU    1        ; Code for echo request
  2506. EPReply    EQU    2        ; Code for echo reply
  2507. ;
  2508. ; Read the packet into the echo buffer
  2509. ;
  2510. RcvEcho    PROC    EXPORT
  2511.                    EXPORT    our_A5 : CODE
  2512.                    EXPORT    our_Buff : CODE
  2513.                    IMPORT    GBOB:DATA
  2514.         BRA.S     checkEcho
  2515. our_A5
  2516.         DC.L      0
  2517. our_Buff
  2518.         DC.L      0
  2519. our_Hops
  2520.         DC.W      0
  2521. our_Ticks
  2522.         DC.L      0
  2523. checkEcho
  2524.         CMP.B     #EP,-(A3)            ; Make sure it's an echo packet
  2525.         BNE.S     RcvEIgnore           ; Ignore it if not
  2526.         LEA       toRHA(A2), A3        ; top of RHA
  2527.         CLR.L     D2                   ; clean up D2
  2528.         MOVE.B    lapType(A3), D2      ; lap type
  2529.         CMP.B     #longDDP, D2         ; check for long header (Type #2 packet)
  2530.         BNE.S     noHops               ; wah... no hops if short packet
  2531.         MOVE.B    lapType+1(A3), D2    ; this is the hop count byte, 1st byte in DDP
  2532.                        ; header
  2533.         AND.B     #$3C, D2             ; mask to middle 4 bits of byte for hop count
  2534.                                        ;     | x | x | H | O | P | S | x | x |
  2535.         ASR.B     #2, D2               ; shift 2 bits to right
  2536.         LEA       our_Hops, A3         ; address of our storage
  2537.         MOVE.B    D2, (A3)             ; move # of hops into our storage
  2538. noHops
  2539.         MOVE.W    #DDPMaxData, D3      ; our buffer is #DDPMaxData in size
  2540.         LEA       our_Buff, A3         ; address of buffer to read packet into
  2541.         MOVE.L    (A3), A3             ; set buffer
  2542.         JSR       2(A4)                ; ReadRest of packet into buffer
  2543.         BEQ.S     RcvEchoReply         ; If no error, continue
  2544.         BRA.S     RcvEchoFail          ; dang…
  2545. RcvEIgnore
  2546.         CLR       D3                   ; Set to ignore packet
  2547.         JMP       2(A4)                ; Ignore it, ReadRest and return
  2548.         BRA.S     RcvEchoFail
  2549. RcvEchoReply
  2550.         CMP.B     #EPReply, -DDPMaxData(A3)    ; make sure it's our reply packet
  2551.                                        ; it shouldn't be anything else, but check
  2552.                                        ; just in case
  2553.         BNE.S     RcvEchoFail          ; if not our reply then blow
  2554.         MOVE.L    A5, D2               ; save dude in D2
  2555.         LEA       our_A5, A5           ; address of our A5 local storage
  2556.         MOVE.L    (A5), A5             ; make A5 our A5 for application global use
  2557.         MOVE.B    #1, GBOB(A5)         ; set flag confirming reception of
  2558.                                        ; echo reply packet
  2559.         LEA       our_Buff, A3         ; address of our local buffer storage into A3
  2560.         MOVE.L    (A3), A3             ; get saved pointer and set buffer.
  2561.         LEA       our_Hops, A5         ; address of hops local storage… notice we
  2562.                                        ; are TRASHING A5 with this!!!!!
  2563.         MOVE.W    (A5), (A3)+          ; copy in hop count to buffer
  2564.         MOVE.L    Ticks, (A3)          ; next copy in Ticks
  2565.         MOVE.L    D2, A5               ; restore dude
  2566.         RTS                            ; return to caller
  2567. RcvEchoFail
  2568.         RTS                            ; return to caller
  2569.         ENDP
  2570. setUpSktListener    PROC    EXPORT
  2571.                             IMPORT    our_A5 : CODE
  2572.                             IMPORT    our_Buff : CODE
  2573.         LEA       our_A5, A0           ; this copies
  2574.         MOVE.L    CurrentA5, (A0)      ; this copies CurrentA5 into our local
  2575.                                        ; storage for global use in the listener
  2576.         MOVE.W    #DDPMaxData, D0      ; max size of data in a packet
  2577.         _NewPtr   CLEAR
  2578.         BNE.S     setUpFailed          ; if NIL then forget it
  2579.         LEA       our_Buff, A1         ; we need to save the pointer reference
  2580.         MOVE.L    A0, (A1)             ;  in a place the listener can find it
  2581.         MOVE.L    A0, D0               ; return value to caller
  2582.         RTS
  2583. setUpFailed
  2584.         CLR.L     D0                   ; tell caller we failed by returning nil
  2585.                                        ; (caller expecting valid ptr returned)
  2586.         RTS
  2587.         ENDP
  2588.         END
  2589. We now resume our regular programming…
  2590. You should typically get an AEP response packet within a few milliseconds.  If there is no response for a period of time, typically about 10 seconds, you should resend your AEP request to account for a lost request or lost packets.  To be really safe, you should resend your AEP request with different data to take into account the response to the first packet coming back later.  The retry time could then be simply set to k*Round_Trip_Time, where the value of k depends upon the request semantics, like total data size.
  2591. This technique of statically setting the retry time is not always adequate to accommodate the varying delays encountered in a internet environment at different times.  You could dynamically adjust the retry time based on an adaptive retransmission algorithm that continuously monitors round trip times and adjusts its timeout parameter accordingly.  To implement an adaptive algorithm, you can record the round trip time for each transaction.  One common technique is to keep the average round trip time as a weighted average and use new round trip times from transactions to change the average slowly.  For example, one averaging technique* uses a constant weighing factor, q, where 0 ≤ q < 1, to weigh the oldest average against the latest round trip time:
  2592.     W_aver = (q * W_aver ) + (( 1 - q) * New_Round_Trip_Time)
  2593. Choosing a value for q close to 1 makes the weighted average immune to changes that last a short time.  Choosing a value for q close to 0 makes the weighted average respond to changes in the delay very quickly.
  2594. The total time (i.e., retry time * retry count) before a request is concluded as failed could be anywhere from 10 seconds to a couple of minutes, depending on the type of the client application and the relative distance between the source and the destination.
  2595. *Douglass Corner, InterNetworking with TCP/IP. KARN, P. and C. PARTRIDGE [August 1987], “Improving Round-Trip Time Estimates in Reliable Transport Protocols”, Proceedings of ACM SIGCOMM 1987.
  2596. NBP Retry Counts
  2597. You cannot really use the AEP to estimate round trip times for NBP packets because you need to use NBP to determine the internet address of the node from which an echo is being sought.  In this case, you have to use the type of device that you are looking for as a heuristic for setting the retry count.  The LaserWriter, for example, may be busy and not respond to a LkUp packet.  In such a case, you might want to do a quick lookup to return a partial list to the user like the Chooser.  You could then do a longer lookup to get a more complete list of mappings.  You should use a “back off” algorithm to make the subsequent lookups further apart to generate progressively less traffic.  Name lookups are expensive and produce a lot of network traffic, and name confirmation is the recommended call to use when confirming mappings obtained through early bindings.  Because Name lookups are expensive, you should avoid searching all the zones in the internet.
  2598. Setting TRel Timer in SendRequest
  2599. AppleTalk Phase 2 drivers allow you to set the TRel timer in SendRequest or NSendRequest calls with ATP XO (exactly once) service so as not to be locked into the pre-AppleTalk Phase 2 time of 30 seconds.  You should set this timer based on the round trip time.  Generally, if the round trip time is less than one second, the default TRel time setting of 30 seconds is adequate.  If the round trip time is more, you can increase the TRel time proportionately.
  2600. xppTimeout and xppRetry
  2601. The two ZIP calls, GetZoneList and GetLocalZones, made on the .XPP driver contain the ATP retry interval (in seconds) and count, in the xppTimeout and xppRetry parameters.  Both these functions are ATP request-response transactions between a node and a router on the network to which the requesting node is attached.  The round trip is relatively short for this transaction, and you should have very small values of xppTimeout and xppRetry, typically two and three, respectively.
  2602. Further Reference:
  2603. •    Inside AppleTalk
  2604. •    Inside Macintosh, Volumes II & V, The AppleTalk Manager
  2605. •    M.NW.Internets
  2606. •    M.NW.AppleTalk2Mac
  2607. NW 15 - Arbitrating the Use of afpMiscUserCommand and afpMiscUserWrite
  2608. Networking    
  2609. Written by:    Jim Luther    September 1992
  2610. This Technical Note discusses a scheme for arbitrating the use of the afpMiscUserCommand and afpMiscUserWrite AppleTalk Filing Protocol (AFP) commands.
  2611. Inside Macintosh Volume V lists two AFP command codes that are reserved for developers. They are afpMiscUserCommand (call number 191) and afpMiscUserWrite (call number 254). Several developers have asked that Apple arbitrate the use of those two AFP calls. This Technical Note describes our recommended solution.
  2612. Because afpMiscUserCommand and afpMiscUserWrite are reserved for developers, the format of the AFP request and reply blocks are undefined except for the first byte of the request block which contains the AFP call number. If the request block is further defined to include a word-aligned long value, that long value can be used to identify a specific developer request. Since most developers have probably already been assigned a unique 4-byte file creator type, we suggest reusing that creator type for the long value. Figure 1 shows the request blocks for afpMiscUserCommand and afpMiscUserWrite with the creator type value. The value of aspMaxCmdSize in the figure is returned by the ASPGetParms function.
  2613. Figure 1  afpMiscUserCommand and afpMiscUserWrite Request Blocks With Creator Type Identifier
  2614. Further Reference:
  2615. •    Inside Macintosh, Volume V, The AppleTalk Manager
  2616. •    M.NW.BorrowedAFP
  2617. NW 16 - Borrowed AFP Sessions
  2618. Networking     
  2619. Written by:    Jim Luther    September 1992
  2620. This Technical Note shows how to borrow the session reference number of an AFP volume mounted by the Macintosh File System. It also shows how to retrieve other information from the file system for a mounted AFP volume.
  2621. Introduction
  2622. The AppleShare Chooser extension allows Macintosh applications to perform almost all volume and file access operations on an AppleTalk Filing Protocol (AFP) file server by translating File Manager commands to their AFP equivalent commands. To access a file server, an application normally calls the File Manager. The File Manager calls the AppleShare external file system (part of the AppleShare Chooser extension) which translates the File Manager command into an AFP call. The AppleShare external file system then calls the .XPP driver. The .XPP driver delivers the AFP call to the server and returns the reply to the AppleShare external file system. The AppleShare external file system translates the reply data (if any) and returns it to the File Manager which returns it to the application. Figure 1 shows the normal flow of commands between a Macintosh application and an AFP file server.
  2623. Figure 1  Application Using the File Server Through the File Manager
  2624. However, there are a few instances for which no equivalent File Manager commands exist to perform operations supported by AFP. In those instances, an application must use the .XPP driver to access the file server with AFP commands.
  2625. Applications accessing a file server with AFP commands need to have an open AFP session with the file server. When no session exists, the application must use the .XPP driver to open an AFP session with the afpLogin (and possibly afpLoginCont) command. However, when an AFP volume on the file server is already mounted by the Macintosh File System, a session is already open with the file server. If the session reference number is retrieved from the .AFPTranslator driver (another part of the AppleShare Chooser extension), that session can be used, with restrictions, to access the file server with AFP commands. Figure 2 shows the flow of commands when a Macintosh application accesses an AFP file server directly through the .XPP driver using the session reference number borrowed from the .AFPTranslator driver.
  2626. Figure 2  Application Using File Server Through the .XPP Driver
  2627.                                with Borrowed Session Reference Number
  2628. The next section of this Technical Note tells how to get the AFP session reference number for a mounted AFP volume from the .AFPTranslator driver. It also lists the restrictions you must observe when using the borrowed AFP session.
  2629. The Server Volume Information Status Call
  2630. The AppleShare external file system performs the translation of File Manager commands to AFP commands and maintains sessions with AFP file servers. The server volume information (AFPSVolInfo)  status call to the .AFPTranslator driver can be used to retrieve several important pieces of information stored by the driver. The information returned by the AFPSVolInfo status call is:
  2631. •    the AFP version used to open the session with the server. This lets you know what possible AFP calls can be made with this session.
  2632. •    the session reference number. The session reference number is passed to the .XPP driver whenever you make an AFP call.
  2633. •    the AFP volume ID number. This is the number you pass to AFP calls that require the volume ID number.
  2634. •    the file server’s internet socket address. This is the same internet socket address returned by the File Manager PBHGetVolParms function in the vMServerAdr field of the GetVolParmsInfoBuffer record.
  2635. •    the user authentication method (UAM) used to establish the session. This is the same word value returned by the File Manager PBHGetLogInInfo function in ioObjType and by the File Manager PBGetVolMountInfo function in the uamType field of the AFPVolMountInfo record.
  2636. •    the user name used to establish the session. This is the same string returned by the File Manager PBHGetLogInInfo function in the string pointed to by ioObjNamePtr and by the File Manager PBGetVolMountInfo function as part of the AFPData field in the AFPVolMountInfo record (the exact location of the user name in the AFPData field in the AFPVolMountInfo record is determined by the userNameOffset field).
  2637. •    the server’s volume icon and mask. This is the same 256-byte icon and mask returned by a control call to the disk driver with csCode = 21.
  2638. •    the string displayed by the Finder’s Get Info dialog (after the word “Where:”). This is the same string returned by a control call to the disk driver with csCode = 21.
  2639. The information list above is returned in a GetVolSessInfoRec record. The GetVolSessInfoRec record is defined as follows:
  2640.     GetVolSessInfoRec = RECORD
  2641.         sessAFPVersion: Integer;       {AFP version number: }
  2642.                                        {    1 = version 1.1 }
  2643.                                        {    2 = version 2.0 }
  2644.                                        {    3 = version 2.1 }
  2645.         sessReferenceNumber: Integer;  {session reference number}
  2646.         sessAFPVolID: Integer;         {AFP volume identifier}
  2647.         sessServerAddress: AddrBlock;  {server internet address}
  2648.         sessUAMType: Integer;          {user authentication method: }
  2649.                                        {    1 = 'No User Authent' }
  2650.                                        {    2 = 'Cleartxt Passwrd' }
  2651.                                        {    3 = 'Randnum Exchange' }
  2652.                                        {    6 = '2-Way Randnum exchange' }
  2653.         sessUserNamePtr: StringPtr;    {ptr to user name string}
  2654.         sessVolIconPtr: Ptr;           {ptr to server volume icon/mask}
  2655.         sessWhereStringPtr: StringPtr; {ptr to "where" information string}
  2656.       END;
  2657. Warning:    sessUserNamePtr, sessVolIconPtr, and sessWhereStringPtr point to data owned by the .AFPTranslator driver. You must copy that data into your program variables before using it.
  2658. The fields in the ParamBlockRec record used for the AFPSVolInfo status call to the .AFPTranslator driver are defined as follows:
  2659. Æ    12    ioCompletion    long    pointer to completion routine
  2660. ¨    16    ioResult    word    result code
  2661. Æ    24    ioRefNum    word    .AFPTranslator reference number
  2662. Æ    26    csCode    word    always AFPSVolInfo
  2663. Æ    28    ioMisc    long    pointer to volume’s VCB
  2664. Æ    32    ioBuffer    long    pointer to GetVolSessInfoRec
  2665. Æ    36    ioReqCount    long    size of data requested
  2666. ¨    40    ioActCount    long    size of data returned
  2667. Here are the detailed descriptions of the parameter block fields:
  2668. ioCompletion    Longword input pointer:  If the AFPSVolInfo status cell is called asynchronously, this must be a pointer to the completion routine or NIL.
  2669. ioResult    Word result value:  The result code from the function.
  2670. ioRefNum    Word input value:  The driver reference number of the .AFPTranslator driver.
  2671. csCode    Word input value:  Always AFPSVolInfo (124).
  2672. ioMisc    Longword input pointer:  A pointer to the volume’s volume control block (VCB).
  2673. ioBuffer    Longword input pointer:  A pointer to the GetVolSessInfoRec where the server volume information is returned.
  2674. ioReqCount    Longword input value:  The size of the GetVolSessInfoRec pointed to by ioBuffer.
  2675. ioActCount    Longword result value:  The size of the data returned in the GetVolSessInfoRec pointed to by ioBuffer.
  2676. The following result codes can be returned by the AFPSVolInfo status call:
  2677. noErr    0    No error.
  2678. badUnitErr    -21    The driver reference number is bad.
  2679. unitEmptyErr    -22    The driver reference number is bad.
  2680. notOpenErr    -28    The driver isn’t open.
  2681. statusErr    -18    The driver can’t respond to this status call.
  2682. paramErr    -50    Either ioReqCount indicates the GetVolSessInfoRec record is too small, or the volume specified by ioMisc is not owned by the .AFPTranslator driver.
  2683. The following code shows how to use the AFPSVolInfo status call to get the server volume information for the volume specified by its volume reference number.
  2684.     USES
  2685.       AppleTalk, Files;
  2686.     
  2687.     CONST
  2688.       { AFP version numbers }
  2689.       AFPVer1_1 = 1;  { AFP version 1.1 }
  2690.       AFPVer2_0 = 2;  { AFP version 2.0 }
  2691.       AFPVer2_1 = 3;  { AFP version 2.1 }
  2692.     
  2693.       AFPSVolInfo = 124;  { server volume information call }
  2694.     
  2695.     TYPE
  2696.       GetVolSessInfoRec = RECORD
  2697.           sessAFPVersion: Integer;        {AFP version number}
  2698.           sessReferenceNumber: Integer;   {session reference number}
  2699.           sessAFPVolID: Integer;          {AFP volume identifier}
  2700.           sessServerAddress: AddrBlock;   {server internet address}
  2701.           sessUAMType: Integer;           {user authentication method}
  2702.           sessUserNamePtr: StringPtr;     {ptr to user name string}
  2703.           sessVolIconPtr: Ptr;            {ptr to server volume icon/mask}
  2704.           sessWhereStringPtr: StringPtr;  {ptr to "where" information string}
  2705.         END;
  2706.     
  2707.     FUNCTION GetVolSessionInfo (theVRefNum: Integer;
  2708.                  VAR theVolSessInfoRec: GetVolSessInfoRec): OSErr;
  2709.       CONST
  2710.         TSigWord = $4244; { HFS volume signature }
  2711.       VAR
  2712.         pb: ParamBlockRec;
  2713.         vcbPtr: QElemPtr;
  2714.         afpTranslatorRefNum: Integer;
  2715.         err: OSErr;
  2716.     BEGIN
  2717.       { get the .AFPTranslator driver refNum }
  2718.       err := OpenDriver('.AFPTranslator', afpTranslatorRefNum);
  2719.       IF err <> noErr THEN
  2720.         BEGIN { couldn't open the driver }
  2721.           GetVolSessionInfo := err;
  2722.           Exit(GetVolSessionInfo);
  2723.         END;
  2724.     
  2725.       { find the VCB with the volume reference number }
  2726.       QHdrPtr(vcbPtr) := GetVCBQHdr;  { pointer to VCB queue header }
  2727.       vcbPtr := QHdrPtr(vcbPtr)^.qHead;  { pointer to first VCB }
  2728.       WHILE (vcbPtr <> NIL) DO
  2729.         BEGIN
  2730.           IF VCB(vcbPtr^).vcbSigWord = TSigWord THEN { must be HFS volume }
  2731.             IF VCB(vcbPtr^).vcbVRefNum = theVRefNum THEN
  2732.               Leave;  { we found the VCB }
  2733.           vcbPtr := vcbPtr^.vcbQElem.qLink;  { next VCB }
  2734.         END;
  2735.       IF (vcbPtr = NIL) THEN
  2736.         BEGIN  { couldn't find the volume }
  2737.           GetVolSessionInfo := nsvErr;
  2738.           Exit(GetVolSessionInfo);
  2739.         END;
  2740.     
  2741.       { make the status call to get the volume session info }
  2742.       WITH pb DO
  2743.         BEGIN
  2744.           ioRefNum := afpTranslatorRefNum;
  2745.           csCode := AFPSVolInfo;
  2746.           ioMisc := Ptr(vcbPtr);
  2747.           ioBuffer := @theVolSessInfoRec;
  2748.           ioReqCount := LongInt(sizeof(GetVolSessInfoRec));
  2749.         END;
  2750.       GetVolSessionInfo := PBStatus(@pb, FALSE);
  2751.     END;
  2752.     
  2753.     FUNCTION DoGetVolSessionInfo (vRefNum: Integer): OSErr;
  2754.       VAR
  2755.         err: OSErr;
  2756.         myVolSessInfoRec: GetVolSessInfoRec;
  2757.         myIconHandle: Handle;
  2758.         myUserName: Str31;
  2759.         myWhereString: Str255;
  2760.     BEGIN
  2761.       err := GetVolSessionInfo(vRefNum, myVolSessInfoRec);
  2762.       IF err = noErr THEN
  2763.         BEGIN
  2764.           WITH myVolSessInfoRec DO
  2765.             BEGIN
  2766.               { copy user name into a string variable }
  2767.               myUserName := sessUserNamePtr^;
  2768.     
  2769.               { allocate a handle and move the icon into it }
  2770.               myIconHandle := NewHandle(kLargeIconSize);
  2771.               IF myIconHandle = NIL THEN
  2772.                 BEGIN
  2773.                   DoGetVolSessionInfo := MemError;
  2774.                   Exit(DoGetVolSessionInfo);
  2775.                 END;
  2776.               BlockMove(sessVolIconPtr, myIconHandle^, kLargeIconSize);
  2777.     
  2778.               { copy where information string into a string variable }
  2779.               myWhereString := sessWhereStringPtr^;
  2780.     
  2781.               { at this point, you can use all of the information just copied }
  2782.               { from myGetVolSessInfoRec or still in myGetVolSessInfoRec }
  2783.     
  2784.               DisposHandle(myIconHandle);
  2785.             END;
  2786.         END;
  2787.       DoGetVolSessionInfo := err;
  2788.     END;
  2789. Session Borrowing Rules and Restrictions
  2790. Warning:    The restrictions listed in this Note must be observed when your program borrows an AFP session owned by the Macintosh File System.
  2791. There is a good reason why Apple has not documented the AFPSVolInfo status call in the past. AFP file servers differentiate users by their sessions and the AppleShare external file system makes certain assumptions about AFP volumes (and their contents) that it has open. If the session owned by the Macintosh File System is used improperly, you can confuse the AppleShare external file system or the file server. The basic rule you should use when borrowing an AFP session owned by the file system is
  2792. If it can be done with File Manager functions, use the File Manager functions—don’t  use AFP calls.
  2793. That means you shouldn’t open or close volumes, directories, files, or a volume’s desktop database, you  shouldn’t use calls that require a file or desktop database to be open, and you definitely should not close the AFP session. If you need to do any of those AFP operations, you should use the .XPP driver to open your own AFP session with the file server.
  2794. The following is a list of AFP calls that are safe to use with a session borrowed from the file system. For each AFP call, there’s an description of what you can do with the call that you cannot do with the File Manager functions.
  2795. afpGetSParms    This call can be used to retrieve the server time and the list of server volumes. For each volume, you also can determine if the volume is password-protected and if the volume contains Apple II configuration information.
  2796. afpSetVolParms    This call can be used to set the backup date of a volume.
  2797. afpChangePassword    This call can be used to change the user’s password.
  2798. afpGetUserInfo    This call can be used to retrieve the specified user’s user ID or primary group ID.
  2799. afpGetSrvrMsg    This call can be used to retrieve the current greeting message or server message. This call is only supported by AFP 2.1 servers. Note: the server message may not be applicable to the user.
  2800. afpMiscUserCommand    reserved for developer use. See Technical Note #323, “Arbitrating Use of afpMiscUserCommand and afpMiscUserWrite.”
  2801. afpMiscUserWrite    reserved for developer use. See Technical Note #323, “Arbitrating Use of afpMiscUserCommand and afpMiscUserWrite.”
  2802. The list continues. However, these calls should be used only when you need to retrieve or set information (such as ProDOS information) that is inaccessible through File Manager functions.
  2803. afpEnumerate    This call can be used to list the contents of a directory when either ProDOS information or specific file or directory attribute information is needed. For all other purposes, the File Manager’s PBGetCatInfo function should be used.
  2804. afpGetVolParms    This call can be used to retrieve the parameters for a particular server volume. For most purposes, the File Manager’s PBHGetVInfo function should be used instead.
  2805. afpSetDirParms    This call can be used to set parameters for a specified directory when either ProDOS information or specific directory attribute information must be set. For all other purposes, the File Manager’s PBSetCatInfo function should be used.
  2806. afpSetFileParms    This call can be used to set parameters for a specified file when either ProDOS information or specific file attribute information must be set. For all other purposes, the File Manager’s PBSetCatInfo function should be used.
  2807. afpGetFlDrParms    This call can be used to retrieve the parameters for a specified file or directory when either ProDOS information or specific file or directory attribute information is needed. For all other purposes, the File Manager’s PBGetCatInfo function should be used.
  2808. afpSetFlDrParms    This call can be used to set parameters for a specified file or directory when either ProDOS information or specific file or directory attribute information must be set. For all other purposes, the File Manager’s PBSetCatInfo function should be used.
  2809. If the AppleShare 3.0 (or later) Chooser extension is used with System 6, you can make the following AFP 2.1 calls to an AFP 2.1 file server. These calls are not supported by the System 6 File Manager.
  2810. afpGetSrvrMsg    See description in list above.
  2811. afpCreateID    This call can be used to create a unique file ID for a specified file.
  2812. afpDeleteID    This call can be used to invalidate all instances of the specified file ID.
  2813. afpResolveID    This call can be used to return information (including the file location) of the specified file ID
  2814. afpExchangeFiles    This call can be used to exchange the contents of two files on a server volume.
  2815. afpCatSearch    This call can be used to search a volume for files or folders that match specified criteria.
  2816. Conclusion
  2817. The AFPSVolInfo status call to the .AFPTranslator driver returns useful information for developers who need to access an AFP file server in ways not supported by the Macintosh File System. However, the restrictions lists in this note must be observed to prevent problems on the client Macintosh or the AFP file server.
  2818. Further Reference:
  2819. •    Inside Macintosh, Volume V, The AppleTalk Manager
  2820. •    M.NW.afpMiscUserCommand
  2821. •    Inside AppleTalk, Second Edition, AppleTalk Filing Protocol
  2822. •    AppleShare 3.0 Developer’s Kit, AppleTalk Filing Protocol Version 2.1
  2823. NW 17 - Data Access Extensions
  2824. Networking    
  2825. Written by:    Chuq Von Rospach and Dan Strnad    May 1992
  2826. This Technical Note discusses coding data access extensions that provide an interface between the Data Access Manager and remote data sources. Each of the functions that a data access extension must implement is described.
  2827. Introduction
  2828. A data access extension is a program that provides an interface between the Data Access Manager and the remote data source. The data access extension implements all of the low-level functions and handles network communication for the Data Access Manager. Because the data access extension implements the low-level Data Access Manager functions, it must return appropriate result codes and handle asynchronous execution of functions as appropriate.
  2829. Note:    Each data access extension contains a flag that indicates to the Data Access Manager whether the data access extension supports asynchronous execution of routines. If an application attempts to make an asynchronous call to a data access extension that has the first bit (bit 0) of the flags field cleared to 0, the Data Access Manager returns a result code of rcDBAsyncNotSupp and terminates execution of the routine. To ensure compatibility     of your data access extension with all applications, your data access extension should support  asynchronous execution of functions. The data access extension flags field is described in the next section, “Contents of a Data Access Extension.”
  2830. As soon as the data access extension begins execution of an asynchronous routine, it should return a noErr result code for the function result and set the result field of the asynchronous parameter block to 1. It should return control to the calling routine as quickly as possible. When it terminates execution of the routine, the data access extension must place the return code in the result field. Result codes for each of the data access extension routines are listed in the next section. The asynchronous parameter block is described in “Asynchronous Execution of Routines” in the Data Access Manager chapter of Inside Macintosh Volume VI, page 8-50. 
  2831. When the data access extension has completed execution of an asynchronous routine, it must call the application’s completion routine pointed to by the completionProc field of the asynchronous parameter block. The completion routine is described in “Asynchronous Execution of Routines” in the Data Access Manager chapter of Inside Macintosh Volume VI, page 8-50.
  2832. The data access extension can use the ddevRef field in the asynchronous parameter block for its own purposes. 
  2833. This Tech Note describes each of the functions that a data access extension must implement. 
  2834. Contents of a Data Access Extension
  2835. A data access extension consists of a file of type 'ddev', located in the Extensions Folder. The data access extension file must contain these resources:
  2836. 'ddev' (function; resource ID is 128)
  2837. 'STR ' (name of data access extension; resource ID is 128)
  2838. 'dflg' (version number and flags; resource ID is 128)
  2839. The 'ddev' resource contains a function that implements all of the low-level Data Access Manager functions. The Data Access Manager calls the ddev function whenever the manager needs to execute a low-level function. 
  2840. Here is a function declaration for a ddev function.
  2841.      FUNCTION MyDDev(params: DDEVParams) : OSErr;
  2842. The params parameter is a parameter block that includes a routine selector. The data access extension parameter block is described in the next section, “Data Access Extension Parameters.” 
  2843. You must set bit 6 of the resource attribute byte to 1 for the 'ddev' resource so that the resource is read into the system heap. Resource attributes are discussed in the Resource Manager chapter of of Inside Macintosh  Volume I.
  2844. The 'STR ' resource must contain a character string of not more than 63 characters that specifies the name of the data access extension. Under tsystem 7.0 or later, the data access extension is assumed  to reside in the "Extensions" folder within the System folder. The data access extension name is a parameter to the DBInit function.
  2845. The 'dflg' resource contains two 4-byte fields, as follows:
  2846. TYPE DDEVFlags = 
  2847. RECORD
  2848.     version:    LongInt;    {data access extension format}
  2849.     flags:        LongInt    {data access extension flags}
  2850. END;
  2851. The version field indicates the version of the data access extension format used for this data access extension. It must be set to 0 for the version 7.0 Data Access Manager.
  2852. The flags field specifies flags that the data access extension must set. At present, only the least significant bit is defined; all other bits must be cleared to 0. Set the flags field to the constant kAsyncSupported (that is, set the least significant bit to 1) if this data access extension supports asynchronous calls, or to 0 if it does not. If an application attempts to make an asynchronous call to a data access extension that has the flags field cleared to 0, the Data Access Manager returns a result code of rcDBAsyncNotSupp. 
  2853. Data Access Extension Parameters
  2854. This section describes the parameter block that the Data Access Manager passes to a data access extension. The section “Data Access Extension Messages” specifies which parameters are significant for each type of routine and whether each value is passed to the data access extension or returned by the data access extension.
  2855. The Data Access Manager passes a parameter block to a data access extension. The parameter block is defined as a DDEVParams record.
  2856. TYPE DDEVParams = 
  2857. RECORD
  2858.     message:    Integer;    {routine selector}
  2859.     ddevStorage:    LongInt;    {storage for use by }
  2860.             { data access extension}
  2861.     asyncPB:    DBAsyncParmBlkPtr;    
  2862.             {pointer to asynch }
  2863.             { parameter block}
  2864.     sessID:    LongInt;    {session ID}
  2865.     returnedID:    LongInt;    {session ID returned}
  2866.     version:    LongInt;    {version number}
  2867.     start:    LongInt;    {session start time}
  2868.     host:    StringPtr;    {name of remote system}
  2869.     user:    StringPtr;    {user name}
  2870.     password:    StringPtr;    {user password}
  2871.     connStr:    StringPtr;    {connection string}
  2872.     network:    StringPtr;    {name of the network}
  2873.     buffer:    Ptr;    {data buffer}
  2874.     err1:    LongInt;    {primary error code returned}
  2875.     err2:    LongInt;    {secondary error code }
  2876.             { returned}
  2877.     item1:    StringPtr;    {pointer to object of error }
  2878.             { message}
  2879.     item2:    StringPtr;    {pointer to object of }
  2880.             { error message}
  2881.     errorMsg:    StringPtr;    {pointer to error message}
  2882.     timeout:    LongInt;    {timeout value for DBGetItem}
  2883.     dataType:    DBType;    {data type}
  2884.     sessNum:    Integer;    {session number}
  2885.     state:    Integer;    {status of the data source}
  2886.     len:    Integer;    {length of data item}
  2887.     places:    Integer;    {decimal places in data item}
  2888.     flags:    Integer;    {flags}
  2889.     abort:    Boolean    {flag for DBBreak}
  2890. END;
  2891. Field Descriptions
  2892. message    The routine selector that tells the data access extension which function to execute. For the values for this field and descriptions of the routines, see the next section, “Data Access Extension Messages.”    
  2893. ddevStorage    Reserved for use by the data access extension. The Data Access Manager sets this field to 0 when it calls the data access extension with the DBOpen message. The data access extension can store any value in this field at that time, and the Data Access Manager retains that value on all subsequent calls to the data access extension. The value of this field does not depend on the session ID; it is the same for all sessions that are using the same data access extension.    
  2894. asyncPB    Pointer to the asynchronous parameter block. If the application is making a synchronous call, this field is NIL. The asynchronous parameter block is described in “Asynchronous Execution of Routines” in the Data Access Manager chapter of Inside Macintosh Volume VI.     
  2895. sessID    The session ID. The data access extension returns the session ID to the DBInit function; all other Data Access Manager functions pass the session ID to the data access extension. 
  2896. The purpose of the session ID is to provide applications with a unique identifier for each active session. The Data Access Manager reads the session ID returned by the data access extension, and then assigns a unique session ID to each session. The Data Access Manager performs the mapping between the session IDs that it provides to applications and the ones used by each data access extension.     
  2897. returnedID    The session ID returned by the DBGetConnInfo function.    
  2898. version    The version number of the data access extension assigned by the developer of the data access extension. It is not the same as the version number in the 'dflg' resource of the data access extension, which indicates the format of the data access extension.     
  2899. start    The time at which the session was opened, in ticks.    
  2900. host    The name of the remote system on which the data source is located.    
  2901. user    The name of the user who is establishing a session.    
  2902. password    The password associated with the user name.    
  2903. connStr    A connection string needed to establish a session.    
  2904. network    A string specifying the network in use for this session.    
  2905. buffer    A pointer to a buffer containing the item to be sent by the DBSend or DBSendItem functions or received by the DBGetItem function.     
  2906. err1    The primary error code returned by the data source.    
  2907. err2    The secondary error code returned by the data source.    
  2908. item1    A pointer to a NULL-terminated string that identifies the first object of the error message returned by the data source. The use of this parameter depends on the specific data source you are using.    
  2909. item2    A pointer to a NULL-terminated string that identifies the second object of the error message returned by the data source. The use of this parameter depends on the specific data source you are using.    
  2910. errorMsg    A pointer to the error message returned by the data source.    
  2911. timeout    The timeout period for the DBGetItem function, in sixtieths of seconds. When the data access extension executes the DBGetItem function, it requests a data item from the remote data source. If the remote data source does not return the requested data item in the amount of time specified by the timeout parameter, the data access extension should cancel execution of the DBGetItem function. The timeout value cannot be used if the DBGetItem function is called asynchronously.     
  2912. dataType    The data type of a requested or returned data item. Data types are described in “Getting Query Results” in the Data Access Manager chapter of Inside Macintosh Volume VI.    
  2913. sessNum    The session number. This number is assigned by the data access extension and is unique for all current sessions for a single data access extension only. The same session number can be assigned to concurrent sessions that use different data access extensions.    
  2914. state    The status of the data source.
  2915. Value    Status
  2916. noErr      Execution of a query successful; ready for another
  2917. rcDBValue    Output data is available
  2918. rcDBError    Execution of a query ended in an error
  2919. rcDBExec    Currently executing a query    
  2920. len    The length of the data item requested or returned.    
  2921. places    The number of decimal places in the data item.    
  2922. flags    Flags returned by the DBGetItem function or sent to the DBSendItem function. For the DBGetItem function, if the flags field is set to kDBLastColFlag (that is, the least significant bit is set to 1), the data item is in the last column of the row. 
  2923. There are no flags currently defined for the DBSendItem function.     
  2924. abort    A parameter used by the DBBreak function. The meaning of this parameter depends on the specific implementation of the data source communications system you are using.    
  2925.         
  2926.  
  2927. Data Access Extension Messages
  2928. There are sixteen values that the Data Access Manager can pass to the data access extension in the messages field of the data access extension parameter block. Thirteen of them correspond exactly to the thirteen low-level functions. The other three are used by the Data Access Manager to initialize and close the data access extension and to allow the data access extension to perform routine periodic tasks. The messages that correspond to low-level routines are not described in this section. Instead, only the parameters they use and the result codes they must be able to return are listed. For descriptions of these routines, see the section “Data Access Manager Routines” in the Data Access Manager chapter of Inside Macintosh Volume VI. The DBOpen, DBClose, and DBIdle messages are described in detail in this section.
  2929. Each parameter in the list is preceded by an arrow that indicates how the parameter is used, as follows:
  2930. Æ    The Data Access Manager passes the value of the parameter as input to the data access extension.
  2931. ¨    The data access extension returns the value of the parameter after the routine has completed execution.
  2932. ´    The Data Access Manager provides a value for the parameter, and the data access extension returns another value.
  2933. DBOpen
  2934. Parameter block
  2935.     Æ    00    message    word    routine selector; kDBOpen
  2936.     ¨    02    ddevStorage    long     storage for data access                         extension
  2937. When an application calls the DBInit function or the DBStartQuery function (which calls the DBInit function), it specifies a data access extension. If that data access extension is not already in memory, the DBInit function loads it into memory and sends it the kDBOpen message. The data access extension should allocate any memory it needs at this time. Because the data access extension can be called by more than one application, it should allocate memory in the system heap rather than the application heap. The data access extension can also return a value in the ddevStorage field of the data access extension parameter block. 
  2938. When the Data Access Manager calls the data access extension, the current resource file is the data access extension file and the default directory is the Extensions Folder on the current startup disk. The data access extension must ensure that both of these values are unchanged when it returns control to the Data Access Manager.
  2939. Result codes
  2940. noErr         0    Data Access Extension initialized successfully
  2941. rcDBError    –    –802    Error initializing data access extension
  2942. DBClose
  2943. Parameter block
  2944.     Æ    00    message    word    routine selector; kDBClose
  2945.     Æ    02    ddevStorage    long     storage for data access extension
  2946. When an application calls the DBEnd function, closing the last open session for a data access extension, the Data Access Manager follows the kDBEnd message with a kDBClose message before removing the data access extension from memory. The data access extension should free any memory that it allocated before returning control to the Data Access Manager.
  2947. Result code
  2948. noErr    0    No error
  2949. DBIdle
  2950. Parameter block
  2951.     Æ    00    message    word    routine selector; kDBIdle
  2952.     ´    02    ddevStorage    long     storage for data access                         extension
  2953. The Data Access Manager periodically sends the kDBIdle message to each data access extension. The data access extension can ignore this message or take the opportunity to perform periodic tasks. Because the timing of the kDBIdle messages might not be regular, the data access extension must not depend on receiving these messages at particular times or with a particular frequency. 
  2954. Result code
  2955. noErr    0    No error
  2956. DBInit
  2957. Parameter block
  2958.     Æ    00    message    word    routine selector; kDBInit
  2959.     ´    02    ddevStorage    long     storage for data access                         extension
  2960.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  2961.     ¨    10    sessID    long    session ID
  2962.     Æ    26    host    long    pointer to name of remote                     system
  2963.     Æ    30    user    long    pointer to user name
  2964.     Æ    34    password    long    pointer to user password
  2965.     Æ    38    connStr    long    pointer to connection string
  2966. The DBInit function initiates a session with a remote data source. See “Controlling the Session” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  2967. Result codes
  2968. noErr          0    No error
  2969. rcDBError   –802    Error initiating session
  2970. DBEnd
  2971. Parameter block
  2972.     Æ    00    message    word    routine selector; kDBEnd
  2973.     ´    02    ddevStorage    long    storage for data access                         extension
  2974.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  2975.     Æ    10    sessID    long    session ID
  2976. The DBEnd function terminates a session with a remote data source and terminates the network connection between the application and the remote computer. See “Controlling the Session” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  2977. Result codes
  2978. noErr        0    No error
  2979. rcDBError        –802    Error ending session
  2980. DBGetConnInfo
  2981. Parameter block
  2982.     Æ    00    message    word    routine selector;                             kDBGetConnInfo
  2983.     ´    02    ddevStorage    long    pointer to storage for ddev
  2984.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  2985.     Æ    10    sessID    long    session ID
  2986.     ¨    14    returned ID    long    session ID returned
  2987.     ¨    18    version    long    version number
  2988.     ¨    22    start    long    session start time in ticks
  2989.     ¨    26    host    long    pointer to name of remote                     system
  2990.     ¨    30    user    long    pointer to user name
  2991.     ¨    38    connStr    long    pointer to connection string
  2992.     ¨    42    network    long    pointer to name of network
  2993.     Æ    78    sessNum    word    session number
  2994.     ¨    80    state    word    status of data source
  2995. The DBGetConnInfo function returns information about the specified session. See “Controlling the Session” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  2996. Result codes
  2997. noErr                0        No error
  2998. rcDBBadSessNum       –808    Invalid session number
  2999. DBGetSessionNum
  3000. Parameter block
  3001.     Æ    00    message    word    routine selector; 
  3002.                     kDBGetSessionNum
  3003.     ´    02    ddevStorage    long     storage for data access                         extension
  3004.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3005.     Æ    10    sessID    long    session ID
  3006.     ¨    78    sessNum    word    session number
  3007. The DBGetSessionNum function returns a session number. See “Controlling the Session” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3008. Result codes
  3009. noErr            0    No error
  3010. rcDBError       – 802    Error getting session number
  3011. DBKill
  3012. Parameters used
  3013.     Æ    00    message    word    routine selector; kDBKill
  3014.     ´    02    ddevStorage    long     storage for data access                         extension
  3015.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3016. The DBKill function cancels the execution of an asynchronous call. See “Controlling the Session” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3017. Result codes
  3018. noErr        0    Asynchronous routine canceled successfully
  3019. rcDBError      –802    Error canceling routine
  3020. DBSend
  3021. Parameter block
  3022.     Æ    00    message    word    routine selector; kDBSend
  3023.     ´    02    ddevStorage    long     storage for data access                         extension
  3024.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3025.     Æ    10    sessID    long    session ID
  3026.     Æ    46    buffer    long    pointer to data buffer
  3027.     Æ    82    len    word    length of data
  3028. The DBSend function sends a query or a portion of a query to the remote data source. See “Sending and Executing Queries” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3029. Result codes
  3030. noErr        0    No error
  3031. rcDBError       –802    Error trying to send text
  3032. DBSendItem
  3033. Parameter block
  3034.     Æ    00    message    word    routine selector;                             kDBSendItem
  3035.     ´    02    ddevStorage    long     storage for data access                         extension
  3036.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3037.     Æ    10    sessID    long    session ID
  3038.     Æ    46    buffer    long    pointer to data buffer
  3039.     Æ    74    dataType    long    data type
  3040.     Æ    82    len    word    length of data item
  3041.     Æ    84    places    word    decimal places in data item
  3042.     Æ    86    flags    word    flags
  3043. The DBSendItem function sends a single data item to the remote data source. See “Sending and Executing Queries” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3044. Result codes
  3045. noErr        0    No error
  3046. rcDBError        –802    Error trying to send item
  3047. DBExec
  3048. Parameter block
  3049.     Æ    00    message    word    routine selector; kDBExec
  3050.     ´    02    ddevStorage    long     storage for data access                         extension
  3051.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3052.     Æ    10    sessID    long    session ID
  3053. The DBExec function initiates execution of a query. See “Sending and Executing Queries” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3054. Result codes
  3055. noErr         0    Execution has begun
  3056. rcDBError   –802    Error trying to begin execution
  3057. DBState
  3058. Parameter block
  3059.     Æ    00    message    word    routine selector; kDBState
  3060.     ´    02    ddevStorage    long     storage for data access                         extension
  3061.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3062.     Æ    10    sessID    long    session ID
  3063. The result code returned by the DBState function indicates the status of the remote data source. See “Sending and Executing Queries” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3064. Result codes
  3065. noErr        0    No error; ready for more text
  3066. rcDBValue     –801    Output data available
  3067. rcDBError    – 802    Execution ended in an error
  3068. rcDBExec           –806    Currently executing query
  3069. DBGetErr
  3070. Parameter block
  3071.     Æ    00    message    word    routine selector; kDBGetErr
  3072.     ´    02    ddevStorage    long     storage for data access                         extension
  3073.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3074.     Æ    10    sessID    long    session ID
  3075.     ¨    50    err1    long    primary error code
  3076.     ¨    54    err2    long    secondary error code
  3077.     ¨    58    item1    long    pointer to first object of                         error 
  3078.                     message
  3079.     ¨    62    item2    long    pointer to second object of                     error 
  3080.                     message
  3081.     ¨    66    errorMsg    long    pointer to error message
  3082. The DBGetErr function retrieves error codes and error messages from a remote data source. See “Sending and Executing Queries” in the Data Access Manager chapter of Inside Macintosh  Volume VI for a complete description of this function.
  3083. Result codes
  3084. noErr        0    No error
  3085. rcDBError      –802    Error retrieving error information
  3086. DBBreak
  3087. Parameter block
  3088.     Æ    00    message    word    routine selector; kDBBreak
  3089.     ´    02    ddevStorage    long     storage for data access                         extension
  3090.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3091.     Æ    10    sessID    long    session ID
  3092.     Æ    88    abort    byte    abort flag
  3093. The DBBreak function can halt execution of a query and reinitialize the remote data source, or it can unconditionally terminate a session with a data source. See “Sending and Executing Queries” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3094. Result codes
  3095. noErr        0    Execution has begun
  3096. rcDBError    –  –802    Break or abort attempt was unsuccessful
  3097. DBGetItem
  3098. Parameter block
  3099.     Æ    00    message    word    routine selector; kDBGetItem
  3100.     ´    02    ddevStorage    long     storage for data access                         extension
  3101.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3102.     Æ    10    sessID    long    session ID
  3103.     Æ    46    buffer    long    pointer to data buffer
  3104.     Æ    70    timeout    long    timeout value
  3105.     ´    74    dataType    long    data type
  3106.     ´    82    len    word    length of data item
  3107.     ´    84    places    word    decimal places in data item
  3108.     ¨    86    flags    word    flags
  3109. The DBGetItem function retrieves the next data item from the data source. See “Retrieving Results” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3110. Result codes
  3111. noErr    0    No error; no next data item
  3112. rcDBValue    –801    A nonzero data item was successfully
  3113.         retrieved
  3114. rcDBNull    –800    The data item was NULL
  3115. rcDBError    –802    No next data item; execution ended in an error
  3116. rcDBBadType    –803    Next data item not of requested data type
  3117. rcDBBreak    –805    Timed out
  3118. DBUnGetItem
  3119. Parameter block
  3120.     Æ    00    message    word    routine selector;                             kDBUnGetItem
  3121.     ´    02    ddevStorage    long     storage for data access                         extension
  3122.     Æ    06    asyncPB    long    pointer to asynch parameter                     block
  3123.     Æ    10    sessID    long    session ID
  3124. The DBUnGetItem function reverses the effect of the last call to the DBGetItem function. See “Retrieving Results” in the Data Access Manager chapter of Inside Macintosh Volume VI for a complete description of this function.
  3125. Result codes
  3126. noErr         0    No error
  3127. rcDBError    –802    Error executing function
  3128. Further Reference:
  3129. •    Inside Macintosh, Volume VI, Data Access Manager chapter
  3130. NW 18 - Will Your AppleTalk Application Support Internets?
  3131. Networking    M.NW.Internets
  3132. Revised by:    Jim Luther    July 1992
  3133. Written by:    Bryan Stearns, Sriram Subramanian, and Pete Helme    April 1986–April 1990
  3134. This Technical Note discusses how AppleTalk applications should work across internets, groups of interconnected AppleTalk networks. It explains the differences between life on a single AppleTalk network and life on an internet.
  3135. Changes since April 1990:  Added references to AppleTalk Data Stream Protocol (ADSP) and the PPC (Program-to-Program) Toolbox and to Inside Macintosh Volume VI, and changed the section “Am I Running on an Internet?” to point out that with AppleTalk Remote Access, you can be on network zero and be connected to a remote network.
  3136. You can read about internets (AppleTalk networks connect by one or more bridges) in Inside AppleTalk. What do you need to do about them?
  3137. Use a High-Level Network Protocol
  3138. Make sure you use the Datagram Delivery Protocol (DDP), or a higher AppleTalk protocol based on DDP, like the AppleTalk Transaction Protocol (ATP), AppleTalk Data Stream Protocol (ADSP), or the PPC Toolbox. Be warned that Link Access Protocol (LAP) packets do not make it across bridges to other AppleTalk networks. Also, don’t broadcast; broadcast packets are not forwarded by bridges (broadcasting using protocols above LAP is discouraged, anyway).
  3139. Use Name Binding
  3140. As usual, use the Name-Binding Protocol (NBP) to announce your presence on the network, as well as to find other entities on the network. Pay special attention to zone name fields; the asterisk (as in “MyLaser:LaserWriter:*”) in a name you look up is now important; it means “my zone only” (see the Zone Information Protocol (ZIP) chapter of Inside AppleTalk  and the AppleTalk Manager chapter of Inside Macintosh Volume VI for information on finding out what other zones exist). The zone field should always be an asterisk when registering a name.
  3141. Pay Attention to Network Number Fields
  3142. When handling the network addresses returned by NBPLookUp (or anyone else), don’t be surprised if the network number field is nonzero.
  3143. Do not assume that there are no routers on the network if your network number is zero. With AppleTalk Remote Access, you can be on network zero and be connected to a remote network. Network applications should look at the SysABridge low-memory global or use the GetZoneList or the GetBridgeAddress or the GetAppleTalkInfo calls to determine if there is a router on the network. 
  3144. Watch for Out-Of-Sequence and Non-Exactly-Once Requests
  3145. Due to a “race” condition on an internet, it’s possible for an exactly-once ATP packet to slip through twice; to keep this from happening, send a sequence number as part of the data with each ATP packet; whenever you make a request, bump the sequence number, and never honor an old sequence number. If you use ADSP or the PPC Toolbox, the protocol will handle out-of-sequence packets and will always deliver data to the client in order.
  3146. Further Reference:
  3147. •    Inside AppleTalk
  3148. •    Inside Macintosh, Volumes II, V, VI, The AppleTalk Manager
  3149. •    Technical Note M.NW.AppleTalk2Mac, AppleTalk Phase 2 on the Macintosh
  3150. •    Technical Note M.NW.AppleTalkTimer, AppleTalk Timers Explained
  3151. •    Technical Note M.NW.AppleTalk2, What’s New With AppleTalk Phase 2
  3152. NW 19 - How the Simple Network Management Protocol (SNMP) Manager Finds Network Cards
  3153. Networking    
  3154. Written by:    Mike Ritter    June 1993
  3155. Apple provides an SNMP Manager that implements an architecture for doing network management on a Macintosh computer. This Tech Note describes how the SNMP manager finds network cards on a Macintosh and explains how you can make the SNMP Manager recognize new types of network cards. This Tech Note is a supplement to the information provided in the Developers kit for SNMP available on the E.T.O. CD-ROM in the MacSNMP Programmer’s Guide.. The kit defines the interfaces to actually gather the information.
  3156. Topics
  3157. • How the SNMP Manager finds a card’s ifGroup statistics
  3158. • How the SNMP Manager finds a card’s link layer statistics
  3159. • How to add a new card type that the SNMP Manager will understand
  3160. Introduction
  3161. This Tech Note assumes that you know something about SNMP and how it works. It also assumes that you know something about the Macintosh computer’s resource manager and driver architecture. This note provides information additional to that provided in the MacSNMP Programmer’s Guide. The method that the SNMP Manager uses to find a networking card depends on the slot manager; therefore, machines that do not support the slot manager will not support SNMP-managed network cards.
  3162. Network Management Framework
  3163. In the IETF (Internet Engineering Task Force) framework for network management there are MIBs (Management Information Bases) for practically every known device, including Ethernet cards, Token Ring cards, FDDI cards, LocalTalk, SMDS, ATM, and others. A MIB describes a minidatabase that a device must support in order to be network manageable. MIBs consist of groups, each of which contains variables and/or rows of variables (tables). One of the standard groups in the standard TCP/IP MIB II (RFC 1213) is the interfaces (if) group. The ifGroup contains variables that describe any (and every) network card. It defines statistics (identified as variables) such as number of packets sent, number of bytes sent, number of bytes received, and so on. As documented in the MacSNMP Programmer’s Guide, the SNMP Manager makes a driver call to a network card to determine this information. But how does it find the driver?
  3164. Finding the Driver
  3165. The SNMP Manager looks through all of the slots (including the pseudo slot for a .ENET0 device) using the Slot Manager. It searches for any device that has the SpBlock.spCategory set to catNetwork (=4.) It assumes that this (and only this category) is a network card. It then looks in its STR# resource (resource ID = 1) for the driver name, using the SpBlock.spCType as the index. The shipping resource is listed below.
  3166. resource 'STR#' (1,"Driver Names for cards"){
  3167. {
  3168. ".ENET",".TOKN","","","","","","",
  3169. "","","","","","","","",
  3170. ".FDDI"
  3171. }};
  3172. Please note that since the spCType of an FDDI card is 17, there are 14 blank entries in this resource. When the original (pre-FDDI final specifications) code for the SNMP Manager was done, FDDI was going to have an spCType of 3. It is unknown why this changed, but Apple Developer Technical Service has promised to be more compact in the future.
  3173. The reason for this hack is that the driver name for many cards is not correctly stored in the SpBlock, while the spCType always is. The SNMP Manager then checks to see if a driver of that name is opened for that slot. If it is, it can then proceed to make the parameter block based statistics calls to gather the information defined in the ifTable in the ifGroup.
  3174. The ifTable in the ifGroup is defined in ASN.1 notation in RFC 1213 as:
  3175.           IfEntry ::=
  3176.               SEQUENCE {
  3177.                   ifIndex        INTEGER,
  3178.             ifDescr        DisplayString,
  3179.                   ifType        INTEGER,
  3180.                   ifMtu            INTEGER,
  3181.                   ifSpeed        Gauge,
  3182.                   ifPhysAddress    PhysAddress,
  3183.                   ifAdminStatus    INTEGER,
  3184.                   ifOperStatus    INTEGER,
  3185.                   ifLastChange    TimeTicks,
  3186.                   ifInOctets        Counter,
  3187.                   ifInUcastPkts    Counter,
  3188.                   ifInNUcastPkts    Counter,
  3189.                   ifInDiscards    Counter,
  3190.                   ifInErrors        Counter,
  3191.                   ifInUnknownProtos    Counter,
  3192.                   ifOutOctets        Counter,
  3193.                   ifOutUcastPkts    Counter,
  3194.                   ifOutNUcastPkts    Counter,
  3195.                   ifOutDiscards    Counter,
  3196.                   ifOutErrors        Counter,
  3197.                   ifOutQLen        Gauge,
  3198.                   ifSpecific        OBJECT IDENTIFIER
  3199.               }
  3200. The SNMP Manager controls the index, as this must be the same for various other tables. Additionally, the ifTable requires that we return an object ID that describes the ifSpecific system on the card and an integer describing the ifType. This tells network management stations where to go to get information specific to this type of network card (things like how many times a Token Ring got a bad token or how many times packet length overruns occurred on an Ethernet card). The SNMP Manager finds this object identifier by using the SpBlock.spCType as the index into another resource of type ‘ifSP’. It also finds the ifType in this resource; this number is defined in RFC 1213 for several networking systems. This resources is defined as:
  3201. /*-------------ifSP • ifSpecific Enumerated Object IDs-----------------*/
  3202. type 'ifSP' {
  3203.     integer = $$Countof(OIDEnum);     /* Number of specific Object IDs */
  3204.     wide array OIDEnum {
  3205.         unsigned long;            /* ifType, from RFC 1213 */
  3206.         wide array ObjectID {        /* Object ID for this card type */
  3207.             unsigned integer = $$Countof(ID);    /* Num of IDs in OID */
  3208.             wide array ID {                        
  3209.                 unsigned long;            /* an ID */                            };
  3210.             };
  3211.         };
  3212. };
  3213. And the resource that is shipping with the card looks like the following:
  3214. data 'ifSP' (1, "ifSpecific Enumerated") {
  3215.     $"0011"           //Three entries in table
  3216.     $"0000 0006"   // Enet type
  3217.     $"0008"           //ENET Object ID
  3218.     $"0000 0001"
  3219.     $"0000 0003"
  3220.     $"0000 0006"
  3221.     $"0000 0001"
  3222.     $"0000 0002"
  3223.     $"0000 0001"
  3224.     $"0000 000A"
  3225.     $"0000 0007"
  3226.     $"0000 0009"   // Token ring type
  3227.     $"0008"           //Token ring Object ID
  3228.     $"0000 0001"
  3229.     $"0000 0003"
  3230.     $"0000 0006"
  3231.     $"0000 0001"
  3232.     $"0000 0002"
  3233.     $"0000 0001"
  3234.     $"0000 000A"
  3235.     $"0000 0009"
  3236.     
  3237.     $"0000 0000 0000"    // #3  type + oid ID
  3238.     $"0000 0000 0000"    // #4  type + oid ID
  3239.     $"0000 0000 0000"    // #5  type + oid ID
  3240.     $"0000 0000 0000"    // #6  type + oid ID
  3241.     $"0000 0000 0000"    // #7  type + oid ID
  3242.     $"0000 0000 0000"    // #8  type + oid ID
  3243.     $"0000 0000 0000"    // #9  type + oid ID
  3244.     $"0000 0000 0000"    // #10 type + oid ID
  3245.     $"0000 0000 0000"    // #11 type + oid ID
  3246.     $"0000 0000 0000"    // #12 type + oid ID
  3247.     $"0000 0000 0000"    // #13 type + oid ID
  3248.     $"0000 0000 0000"    // #14 type + oid ID
  3249.     $"0000 0000 0000"    // #15 type + oid ID
  3250.     $"0000 0000 0000"    // #16 type + oid ID
  3251.     $"0000 000F"   // FDDI Type
  3252.     $"0008"           //FDDI Object ID
  3253.     $"0000 0001"
  3254.     $"0000 0003"
  3255.     $"0000 0006"
  3256.     $"0000 0001"
  3257.     $"0000 0002"
  3258.     $"0000 0001"
  3259.     $"0000 000A"
  3260.     $"0000 000E"
  3261. };
  3262. Please note again that since the spCType of FDDI is 17, there are 14 blank entries in this resource.
  3263. Both of these resources are stored in the SNMP Manager file in the Extensions folder. If you are releasing a new type of networking card and want it to be network manageable, you must perform the following steps.
  3264. To support the generic ifGroup (minimum support to claim network compatibility) you must 
  3265. •    implement the driver call described in the MacSNMP Programmer’s Guide for network cards; specifically, it must support the following driver selector: 242 (LapGetLinkStatus).
  3266. •    ensure that the STR# resource of ID #1 in the SNMP Manager file in the Extensions folder has the name of your network driver in the correct string (the one that has an index equal to the spCType of your card).
  3267. •    ensure that the ‘ifSP’ resource of ID #1 in the same place has the correct entry for your network card’s object ID. This object ID will only be used for display.
  3268. When adding your entry to either of these resources, please don’t overwrite the entire resource. Just add your specific entries to the resource. Other cards or future release may have already altered the resources beyond what is listed above and you would not want to erase useful information and cause other people’s hardware to fail.
  3269. To support the specific MIB for your network group is a bit more complicated. The shipping SNMP Manager defines a driver interface for Ethernet and Token Ring cards to use to return the network specific statistics. And future versions of the AppleTalk Connection Product will have Agents that can actually report these values to the SNMP Manager. The Agent will depend upon the correct driver name from the STR# resource described above. Thus, if you are building an Ethernet or Token Ring card you will only have to implement the correct driver calls as documented in the MacSNMP Programmer’s Guide to become fully network manageable. 
  3270. If you are building a third type of card, the problem is more difficult. First the IETF has not defined MIBs for most other types of cards, and second there is no definition for which selector returns which information from the card’s driver. As new cards become available Apple may provide Link Layer agents that can manage these new cards. Apple Developer Technical Support should be notified if you are building a new card. There are several procedures to define new card interfaces, and they can recommend the best alternative for your card type. 
  3271. Conclusion
  3272. Please talk to Apple Developer Technical Support if you are developing a new type of networking card for the Macintosh.
  3273. Further Reference:
  3274. •    Inside Macintosh, Volume V, Slot manager
  3275. •    Designing Cards and Drivers for the Macintosh Family
  3276. •    MacSNMP Programmer’s Guide
  3277. •    RFC 1157, A Simple Network Management Protocol
  3278. •    RFC 1213, Management Information Base for Network Management of TCP/IP-Based Internets: MIB-II
  3279. •    RFC 1155, Structure and Identification of Management Information for TCP/IP- Based Internets
  3280. NW 20 - PAP Status Buffer
  3281. Networking    
  3282. Revised by:    Jim Luther    October 1992
  3283. Written by:    Jim Luther (in a previous life)    November 1990
  3284. This Technical Note shows the format of the ATP data part of Printer Access Protocol (PAP) OpenConnReply and Status AppleTalk response packets. A PAP client returns this information in its implementation of the PAPStatus and PAPOpen calls. The status buffer format is shown for both LaserWriter and ImageWriter (with the ImageWriter II/LQ LocalTalk Option card installed) printers.
  3285. Changes since November 1990: Much of this information originally appeared in Apple II AppleTalk Technical Note #9.
  3286. Topics
  3287. •    The format of OpenConnReply and Status PAP status buffers from the LaserWriter printer and from the ImageWriter II/LQ LocalTalk Option card
  3288. •    Macintosh PAP client implementation information
  3289. OpenConnReply and Status AppleTalk response packets contain up to 260 bytes of data in the ATP data part of the packet. Implementations of PAPStatus and PAPOpen calls typically return this information into an application supplied “status buffer.” In a Status packet, the first 4 bytes of the status buffer are unused. The first 4 bytes of an OpenConnReply packet’s status buffer contain the ATP responding socket number, the flow quantum from the printer or print server, and a result code. So, in either packet format, the actual “status data” starts at offset $04 in the status buffer.
  3290. The LaserWriter printer returns its status data in the form of a Pascal string. That string is usually something almost suitable to display on the screen (for example, “status: idle” or “job: Fred; document: My LaserWriter is on fire; status: busy; source: AppleTalk”). The status text displayed in the LaserWriter Driver dialog boxes is a result of the information contained in the statusString; it is not the statusString returned by PAPStatus or PAPOpen. Figures 1 and 2 show the format of the ATP data part of the Status and OpenConnReply packets returned by a LaserWriter.
  3291. Figure 1—The Status Packet From a LaserWriter
  3292. Figure 2—The OpenConnReply Packet From a LaserWriter
  3293. The ImageWriter II/LQ LocalTalk Option card does not return a status string. Instead, it returns a statusBits word where each bit within that word has a specific meaning. An application can interpret the statusBits word and generate an appropriate message to display. Figures 3, 4, and 5 show the format of the ATP data part of the Status and OpenConnReply packets returned by the ImageWriter II/LQ LocalTalk Option card and the individual bit definitions of the statusBits word.
  3294. Figure 3—The Status Packet From an ImageWriter II/LQ LocalTalk Option Card
  3295. Figure 4—The OpenConnReply Packet From an ImageWriter II/LQ LocalTalk Option Card
  3296. Figure 5—The statusBits Word From an ImageWriter II/LQ LocalTalk Option Card
  3297. There are two additional things to note when interpreting the statusBits word returned by an ImageWriter II/LQ LocalTalk Option card:
  3298. •    If a sheet feeder is installed (bit 14 = 1), running out of paper results in a “Paper jam error” (bit 10 = 1) instead of a “Paper out error” (bit 13).
  3299. •    The ImageWriter II/LQ LocalTalk Option card has been known to randomly return all 1s in the high byte (bits 8–15) of the statusBits word. When this happens, the statusBits word is invalid and an application should repeat the PAPStatus call to get valid information.
  3300. The Information in This Note and PAP Client Implementations
  3301. This Technical Note does not show how to make PAP calls—it only shows the format of the ATP data parts of OpenConnReply and Status AppleTalk response packets as returned by LaserWriter and ImageWriter printers. This device-specific data is important to some developers, and that’s why we’re publishing it.
  3302. It’s important that you realize the PAP client driver embedded in Apple’s current LaserWriter and ImageWriter printer drivers is unsupported by Apple. That PAP driver is unsupported because Apple engineering has always reserved the right to change its implementation as well as its calling interface, and because it will not be present in the QuickDraw GX printer drivers. To run under QuickDraw GX, applications using the PAP client driver embedded in Apple’s printer drivers must be revised to use another PAP client driver.
  3303. Apple supplies a PAP client driver that can be linked with your program. You can license that driver from Apple’s Software Licensing department (AppleLink: SW.LICENSE). As an alternative to using our PAP client driver, you can write your own PAP client. This can be a time-consuming operation (depending on how versed you are with asynchronous AppleTalk programming), but it is also very unlikely to break under future systems. Several developers have done it, and it is fairly straightforward. See the Printer Access Protocol (PAP) chapter of Inside AppleTalk for details.
  3304. Further Reference:
  3305. •    Inside AppleTalk, Second Edition, Chapter 10, “Printer Access Protocol”
  3306. •    PostScript Language Reference Manual, Appendix D, “Apple LaserWriter”
  3307. •    ImageWriter LQ Reference, Appendix G, “Interface Specifications, Printer Status Register”
  3308. •    “Print Hints: Looking Ahead to QuickDraw GX” by Pete (“Luke”) Alexander, develop Issue 13
  3309. NW 21 - Data Servers on AppleTalk
  3310. Networking    
  3311. Revised by:        March 1988
  3312. Written by:    Bryan Stearns    April 1985
  3313. Many applications could benefit from the ability to share common data between several Macintoshes, without requiring a file server. This technical note discusses one technique for managing this AppleTalk communication.
  3314. There are four main classes of network “server” devices: 
  3315. Device Servers, such as the LaserWriter, allow several users to share a single hardware device; other examples of this (currently under development by third parties) are modem servers and serial servers (to take advantage of non-intelligent printers such as the ImageWriter). 
  3316. File Servers, such as AppleShare, which support file access operations over the network. A user station sends high-level requests over the network (such as “Open this file,” “Read 137 bytes starting at the current file position of this file,” “Close this file,” etc.).
  3317. Block Servers, which answer to block requests over the network. These requests impart no file system knowledge about the blocks being passed, i.e., the server doesn’t know which files are open by which users, and therefore cannot protect one user’s open file from other users. Examples of this type of server are available from third-party developers.
  3318. Data Servers, which answer to requests at a higher level than file servers, such as “Give me the first four records from the database which match the following search specification.” This note directs its attention at this type of server.
  3319. A data server is like a file server in that it responds to intelligent requests, but the requests that it responds to can be more specialized, because the code in the server was written to handle that specific type of request. This has several added benefits: user station processing can be reduced, if the data server is used for sorting or searching operations; and network traffic is reduced, because of the specificity of the requests passed over the network. The data server can even be designed to do printing (over the network to a LaserWriter, or on a local ImageWriter), given that it has the data and can be directed as to the format in which it should be printed.
  3320. ATP: The AppleTalk Transaction Protocol
  3321. ATP, the assured-delivery AppleTalk Transaction Protocol, can be used to support all types of server communications (the LaserWriter uses ATP for its communications!). Here is a possible scenario between two user stations (“Dave” and “Bill”) and a data server station (“OneServer”, a server of type “MyServer”). We’ve found that the “conversational” analogy is helpful when planning AppleTalk communications; this example is therefore presented as a conversation, along with appropriate AppleTalk Manager calls (Note that no error handling is presented, however; your application should contain code for handling errors, specifically the “half-open connection” problem described below).
  3322. Establishing the Connection
  3323. Each station uses ATPLoad to make sure that AppleTalk is loaded. The server station, since it wants to accept requests, opens a socket and registers its name using NBPRegister. The user stations use NBPLookUp to find out the server’s network address. This looks like this, conversationally:
  3324. Server:     “I’m ready to accept        ATPLoad        Opens AppleTalk
  3325.     requests!”            OpenSocket        Creates socket
  3326.                     NBPRegister        Assigns name to socket
  3327.                     ATPGetRequest    queue a few asynchronous
  3328.                     ATPGetRequest    calls, to be able to handle several
  3329.                     ATPGetRequest    users
  3330. Dave:    “Any ‘MyServers’        ATPLoad        Opens AppleTalk
  3331.     out there?”            NBPLookup        look for servers, finds OneServer
  3332. Dave:     “Hey, MyServer! What        ATPRequest        Ask the server which socket to
  3333.     socket should I talk to you                use for further communications
  3334.     on?”
  3335. Bill:    “Any ‘MyServers’        ATPLoad        Opens AppleTalk
  3336.     out there?”            NBPLookup        look for servers, finds OneServer
  3337. Bill:     “Hey, MyServer! What        ATPRequest        Ask the server which socket to
  3338.     socket should I talk to you                use for further communications
  3339.     on?”
  3340. Server:    “Hi, Dave! Use Socket N.”    ATPOpenSkt        Get a new socket for talking to Dave
  3341.                     ATPResponse        Send Dave the socket number
  3342.                     ATPGetRequest    Replace the used GetRequest
  3343. Server:    “Hi, Bill! Use socket M.”        ATPOpenSkt        Get a new socket for talking to Bill
  3344.                     ATPResponse        Send Bill the socket number
  3345.                     ATPGetRequest    Replace the used GetRequest
  3346. From this point on, the server knows that any requests received on socket N are from Dave, and those received on socket M are from Bill. The conversations continue, after a brief discussion of error handling.
  3347. Half-Open Connections
  3348. There is a possibility that one side of a connection could go down (be powered off, rebooted accidently, or simply crash) before the connection has been officially broken. If a user station goes down, the server must throw away any saved state information and close that user’s open socket. This can be done by requiring that the user stations periodically “tickle” the server: every 30 seconds (for example) the user station sends a dummy request to the server, which sends a dummy response. This lets each side of the connection know that the other side is still “alive.”
  3349. When the server detects that two intervals have gone by without a tickle request, it can assume that the user station has crashed, and close that user’s socket and throw away any accumulated state information.
  3350. The user station should use a vertical-blanking task to generate these tickle requests asyncronously, rather than generating them within the GetNextEvent loop; this avoids problems with long periods away from GetNextEvent (such as when a modal dialog box is running). This task can look at the time that the last request was made of the server, and if it’s approaching the interval time, queue an asynchronous request to tickle the server (it’s important that any AppleTalk calls made from interrupt or completion routines be asynchronous).
  3351. If a user station’s request (including a tickle request) goes unanswered, the user station should recover by looking for the server and reestablishing communications as shown above (beginning with the call to NBPLookUp).
  3352. More information about half-open connections can be found in the Printer Access Protocol chapter of Inside LaserWriter, available from APDA.
  3353. Using the Connection
  3354. The user stations Dave and Bill have established communications with the server, each on its own socket (note that the user stations have not had to open their own sockets, or register names of their own, to do this—the names we’re using are merely for explanational convenience). They are also automatically tickling the server as necessary.
  3355. Now the user stations make requests of the server as needed: 
  3356. Bill:    “I’d like to use the sales        ATPRequest        Bill opens a database.
  3357.     figures for this year.”
  3358. Server:    “Ok, Bill.”            ATPResponse        The server checks to make sure that
  3359.                                 no one else is using that database.
  3360. Dave:    “Hey, Server - I’m still here!”    ATPRequest        Dave notices that the interval time is                                 approaching, and makes a tickle 
  3361.                                 request.
  3362. Server:    “Ok, Dave.”            ATPResponse        The server resets its “last time I heard                                 from Dave”.
  3363. Bill:    “Please print the figures        ATPRequest        Bill asks for specific data.
  3364.     for January thru June.”
  3365. Server:    “Ok, Bill.”            ATPResponse        The server does a database search
  3366.                                 sorts the results, and prints them
  3367.                                 on a local Imagewriter.
  3368. Dave:    “I’d like to use the sales        ATPRequest        Dave opens a database.
  3369.     figures for this year.”
  3370. Server:    “Sorry, Dave, I can’t do that.    ATPResponse        The server finds that Bill is using that
  3371.     Bill is using that database.”                data.
  3372. Closing the Connection
  3373. The user stations continue making requests of the server, until each is finished. The type of work being done by the server determines how long the conversation will last: since the number of sockets openable by the server is limited, it may be desirable to structure the requests in such a way that the average conversation is very short. It may also be necessary to have a (NBP named) socket open on the user station, if the server needs to communicate with the user on other than a request-response basis. Here is how our example connections ended:
  3374. Dave:    “Thank you, server, I’m done    ATPRequest        Dave tells the server he’s finished.
  3375.     now. You’ve been a big help.”        
  3376. Server:    “Ok, Dave. Bye now.”        ATPResponse    T    the server kisses Dave goodbye.
  3377.                     ATPCloseSkt        After the Response operation                                     completes, the server closes
  3378.                                 the socket Dave was using. It also                     ATPCloseSkt        notices that Bill hasn’t sent a request 
  3379.                                 in more than two intervals, and closes                                 Bill’s socket, too.
  3380. The user station can forget about the socket it was using on the server; if it needs to talk with the server again, it starts at the NBPLookUp (just in case the server has moved, gone down and come up, etc.).
  3381. Further Reference:
  3382. •    The AppleTalk Manager Inside LaserWriter
  3383. NW 22 - SNMP Transports
  3384. Network    
  3385. Written by:    Mike Ritter and Vincent Lubet    June 1993
  3386. This Technical Note explains how to write an SNMP (Simple Network Management Protocol) Transport. An SNMP Transport is responsible for communicating between the SNMP Manager and a particular network layer. Thus, if you were writing a new network stack for the Macintosh and wanted it to use the SNMP Manager, you would write an SNMP Transport for your network stack. 
  3387. Topics
  3388. • Creating and initializing an SNMP Transport
  3389. • Reading and Writing SNMP Packets 
  3390. Introduction
  3391. It is assumed in this document that you understand MacSNMP, object-oriented programming and the Shared Library Manager. The SNMP Manager is built using the Shared Library Manager and is a set of shared libraries. The SNMP Manager shared library contains the implementation of the base class for an SNMP Transport. Your transport must be a subclass of this SNMP Transport class. For more information on MacSNMP and the Shared Library Manager see the E.T.O. CD ROM.
  3392. This Tech Note provides some additional information needed to construct an SNMP Transport for a particular network stack. An SNMP Transport is required to know about all of the specific idiosyncrasies of SNMP for a particular network stack. SNMP was originally defined to run over the TCP stack using UDP. The IETF (Internet Engineering Task Force) has also defined how to run SNMP over three other network stacks: AppleTalk, IPX, and OSI. These methods are documented by the IETF proposed standards: RFC 1419—SNMP over AppleTalk, RFC 1420—SNMP over IPX, and RFC 1418—SNMP over OSI. There is also an informational RFC draft that describes what must be defined to allow SNMP to run over any particular network stack.
  3393. Apple provides SNMP transports that support the TCP stack and the AppleTalk stack. The TCP SNMP Transport provides knowledge of IP addresses, listens on the well-known SNMP sockets, sends SNMP packets on UDP, and resolves addresses in dotted notation into IP addresses for sending Traps. (An SNMP Trap is the method that SNMP entities use to send unsolicited warning messages to each other and should not be confused with a Macintosh Operating System Trap.) The AppleTalk SNMP Transport likewise provides knowledge of AppleTalk addresses, listens on the well-known SNMP sockets, sends SNMP packets on DDP, and resolves NBP (Name Binding Protocol) names into AppleTalk addresses for sending Traps. Similarly, a new SNMP Transport would have to provide these same services: understanding the new network addresses, listening for SNMP packets, sending SNMP packets, and resolving stored console addresses to network addresses for sending Traps.
  3394. SNMP Transports
  3395. Figure 1—An SNMP Transport provides the interface between the SNMP Manager and a particular network stack.
  3396. Creating an SNMP Transport
  3397. The file Transport.h defines the SNMP Transport class. To create an SNMP Transport, you must subclass the SNMP Transport class. The Shared Library Manager allows a run-time link of your SNMP Transport subclass with the base object SNMP Transport provided in the SNMP Manager shared library. The definition of the SNMP Transport object is as follows:
  3398. /**********************************************************************
  3399. ** Class TSNMPTransport 
  3400. ***********************************************************************/
  3401. #define kTSNMPTransportID     "snmp:mgr$TSNMPTrans"
  3402. #define kLIB_TransID      "snmp:trans$"    // Library ID for an SNMP Transport 
  3403. class TSNMPTransport : public TDynamic 
  3404. {
  3405. public:
  3406.     
  3407.                 TSNMPTransport();
  3408.     virtual        ~TSNMPTransport();
  3409.     virtual Boolean    IsValid() const;        // returns valid or not    
  3410.     virtual OSErr     InitSNMPTransport(    
  3411.         TransportTag        aTag,
  3412.         TIAddressPtr        aTrapSocketPtr,
  3413.         TIAddressPtr        aReqSocketPtr,
  3414.         Boolean        ahandlesresolution,
  3415.         short            aWritebufsize,
  3416.         TransportRWProcPtr    aWriteProcPtr,
  3417.         short            aNumofReads,
  3418.         short            aReadTIAddrSRCmax,
  3419.         short            aReadTIAddrDESTmax,
  3420.         short            aReadbufsize,
  3421.         TransportRWProcPtr    aReadProcPtr);
  3422.         
  3423.     virtual void        SNMPWriteDone(SNMPTransportBlockPtr snmpPtr);
  3424.     virtual void        SNMPReadDone(SNMPTransportBlockPtr snmpPtr);
  3425.     
  3426.     TSNMPManagerPrv*    fSNMPManagerPtr;
  3427.                 
  3428. friend TSNMPManagerPrv;
  3429. protected:
  3430.         Boolean    fValid;
  3431.         Boolean    fhandlesresolution;
  3432.         short        fNumofReads;
  3433.         short        fReadTIAddrSRCmax;
  3434.         short        fReadTIAddrDESTmax;
  3435.         short        fReadbufsize;
  3436.         short        fWritebufsize;
  3437. private:
  3438.         
  3439.         TransportTag        fTag;
  3440.         TIAddressPtr        fTrapSocketPtr;
  3441.         TIAddressPtr        fReqSocketPtr;
  3442.         TransportRWProcPtr    fWriteProcPtr;
  3443.         TransportRWProcPtr    fReadProcPtr;
  3444. };
  3445. To start an SNMP Transport you must instantiate it. For the AppleTalk SNMP Transport, we install a process on the AppleTalk transition queue that tells us when AppleTalk is coming up or going down and instantiate or destroy the Transport as appropriate. For the TCP SNMP Transport, an INIT31 instantiates the Transport and it is never destroyed. For your Transport you must provide the code that instantiates and destroys your Transport.
  3446. When a Transport is instantiated the base class constructor is called first. The base class constructor fills in the fSNMPManagerPtr field with a pointer to a class TSNMPManagerPrv, which can be cast to a pointer to the class TSNMPManager defined in TSNMP.h. This pointer can be used to access the members of the TSNMPManager class. The constructor also adds a pointer to your SNMP Transport object to a queue of transports so that it can find you later, and if everything worked, sets the fValid field to true. Your constructor is then called. If the fValid field is not set to true on the entrance to your constructor, you should bail out of the constructor immediately. If your constructor fails for some reason, you should set the fValid field to false. The Shared Library Manager will then clean up the object so that a partially constructed one does not remain.
  3447. Initializing an SNMP Transport
  3448. After your Transport is constructed it must be initialized. Your transport will not work until InitSNMPTransport() is called. This routine sets all of the fields in the SNMP Transport from the parameter values that you pass in. You must call the inherited InitSNMPTransport member function if you override it. The following fields must be set.
  3449. ->    TransportTag        aTag
  3450. A long that uniquely identifies a transport (analogous to OSType)
  3451. ->    TIAddressPtr        aTrapSocketPtr 
  3452. Opaque address of where the Transport listens for Traps
  3453. ->    TIAddressPtr        aReqSocketPtr
  3454. Opaque address of where the Transport listens for Requests
  3455. ->    Boolean            ahandlesresolution
  3456. True if the transport can send Traps
  3457. ->    short            aWritebufsize
  3458. Maximum size of write buffers
  3459. ->    TransportRWProcPtr        aWriteProcPtr
  3460. Address of the write procedure
  3461. ->    short            aNumofReads
  3462. Maximum number of reads issued at once
  3463. ->    short            aReadTIAddrSRCmax
  3464. Maximum length of source address for read operations
  3465. ->    short            aReadTIAddrDESTmax
  3466. Maximum length of destination address for read operations
  3467. ->    short            aReadbufsize
  3468. Maximum size of a read buffer
  3469. ->    TransportRWProcPtr        aReadProcPtr
  3470. Address of the read procedure
  3471. The aReadProcPtr and aWriteProcPtr have the following definition:
  3472. typedef void (*TransportRWProcPtr)(SNMPTransportBlockPtr dataPtr);    
  3473. It is recommended that the TransportTag be four human readable ASCII characters that describe the network layer that the Transport talks to. If multiple Transports with the same TransportTag are instantiated, the SNMP Manager will ignore all but the first one instantiated. For the AppleTalk SNMP Transport the tag is 'DDP ', for the TCP SNMP Transport the tag is 'UDP '. This value is used in the Trap Table in the Macintosh Agent to determine which Transport understands the console address stored in a particular row of the table. The sockets are where the Transport listens for Traps and Requests. The SNMP Manager does not understand the format of these addresses and just passes them along to your Transport. They are also used as the source of Traps or Responses sent. Finally, they allow the SNMP Manager to determine what type of packet it is decoding before parsing the raw ASN.1 data. In our Transports we have stored pointers to the actual bits of the network layer addresses in these fields. The aWritebufsize and aReadbufsize are the size of buffers that the SNMP Manager allocates for your Transport to use.
  3474. Reading SNMP Packets
  3475. Finally, InitSNMPTransport() tries to issue aNumofReads outstanding reads by calling your aReadProc() with a filled in SNMPTransportBlock as shown in Figure 2. The SNMPTransportBlock is defined as follows:
  3476. struct SNMPTransportBlock {
  3477.     unsigned long        qLink;        // reserved for pointer to next block
  3478.     short            qType;        // reserved for queue routines
  3479.     TSNMPTransport*     transport;    // who was asked to read or write block
  3480.     SNMPError        result;    // after request is serviced
  3481.     void*             destopaqueData;// destination address to be resolved                             (used in write trap only)
  3482.     TIAddressPtr        destination;    // who the packet was sent to 
  3483.     TIAddressPtr        source;    // who sent the packet to us
  3484.     void *            UserDataPtr;    // Transport work space
  3485.     Boolean        freeFlag;    // is the write finished?
  3486.     Boolean        readFlag;    // managed by SNMP Manager
  3487.     PacketElementPtr    pktelementPtr;// managed by SNMP Manager
  3488.     SNMPPacketStructPtr    packetPtr;    // managed by SNMP Manager
  3489. };
  3490. The aReadProc() must be able to catch both incoming Traps and Requests. It must also be able to be called at any time, thus you must not allocate memory using the normal Macintosh memory calls. You may use the area pointed to by UserDataPtr for any scratch you might need. The SNMP Manager has preallocated this area for you according to the sizes you set in aReadbufsize. It must also return immediately. When a read actually completes you must call SNMPReadDone() after filling in the data, the source and destination addresses, the actual number of bytes read (in packetPtr->packetPiece.dataSize), the freeFlag (set to false), and the result (snmpNoError if it worked.) 
  3491. Warning:    If the freeFlag is incorrectly set, the SNMP Manager will become hopelessly confused.
  3492. After the read packet is processed by the SNMP Manager it issues another read call to aReadProc() so that there will always be some number of outstanding reads. If there are no outstanding reads at any time it is allowable for your transport to drop SNMP packets. 
  3493. Figure 2—Layout of SNMPTransportBlock when aReadProc() called. Only the fields that the Transport may need to access are shown.
  3494. When your Transport is deleted you must ensure that your completion routines will not be called after your destructor is finished and your Transport object is gone. You may have to wait for asynchronous writes to complete and cancel any outstanding reads. The base class destructor will ensure that any packets you have queued up for processing will be thrown away.
  3495. Figure 3—Layout of SNMPTransportBlock when the SNMP Manager calls aWriteProc() with a response to an SNMP Request.*
  3496. *Only the fields that the Transport may need to access are shown.
  3497. Writing SNMP Packets
  3498. After a packet is processed by the SNMP Manager, it will almost always generate a Response packet. The SNMP Manager will either respond to a Request or generate a Trap. In the cases of a simple Response the SNMP Manager will call your aWriteProc() with an SNMPTransportBlock filled out as shown in Figure 3. Your aWriteProc() may be called at any time, thus you must not allocate memory using the normal Macintosh memory calls. You may use the area pointed to by UserDatPtr for any scratch memory you need. The SNMP Manager has preallocated this area for you according to the sizes you set in aWritebufsize. The destination socket is the same block as was passed in on the read as the source socket, the source socket is your initialized fRequestSocketPtr, the packetPtr points to the SNMP data to put on the wire. You must return immediately from the call to aWriteProc(). After the write completes you should fill in the result, set the freeFlag to true, and call SNMPWriteDone() so that the SNMP Manager can free up the memory it allocated.
  3499. Warning:    If the freeFlag is incorrectly set the SNMP Manager will become hopelessly confused.
  3500. If your Transport can send Traps it must set the fHandlesResolution field to true. It is strongly encouraged that your transport handle Traps, if it did not, it would not be fully compliant with the SNMP standard. When a Trap is generated, the SNMP Manager will determine if the Trap is supposed to be sent to a console that supports your Transport type by looking through the Trap table in the Macintosh System MIB implemented by the Macintosh Agent. If so, it will issue a call to your aWriteProc() as above, except that the destOpaqueData will point to a block that the SNMP Manager has procured from the trapDestination field in the Trap Table in the Macintosh Agent. It is up to you to define how this address will be stored. However, it must be nonvolatile between reboots of the system. For the AppleTalk SNMP transport, we store the NBP name of the console as specified in the AppleTalk over SNMP RFC. For the TCP SNMP Transport, we store the IP address of the console in dotted notation The Transport is responsible for turning this address into the wire address of the console. Everything else is as above. You must return immediately after the call to your aWriteProc() and call SNMPWriteDone() when the Trap write completes.
  3501. The Trap Table is implemented by the Macintosh Agent and is defined in ASN.1 by the Macintosh System MIB as:
  3502. TrapRequestEntry     ::= SEQUENCE {
  3503. trapIndex        INTEGER,            // unsigned long
  3504. trapCommunity        MacintoshDisplayString,    // opaque data 
  3505. trapProtocol        MacOSType,            // four bytes
  3506. trapDestination    OCTET STRING,            // opaque data
  3507. trapValidity        INTEGER            // 1 = valid, 2 = invalid
  3508. }
  3509. The two fields that an SNMP Transport author must define are the trapProtocol and the trapDestination. The trapProtocol is compared by the SNMP Manager to the TransportTag and is used to identify which SNMP Transport will be able to resolve the trapDestination entry and send the Trap. The trapProtocol field must contain the same value that was initialized in the transportTag field. Some care should be given to the format of the trapDestination as network managers will have to enter these addresses by hand from a console. 
  3510. Summary
  3511. An SNMP Transport provides an interface between the SNMP Manager and a network layer of a particular network stack. It must be able to be called at any time, thus cannot depend on the Macintosh memory calls. A Transport must understand how a Trap destination (console address) is to be stored in the Macintosh Agent’s Trap Table. This address format must be stable between reboots of the system and must be resolvable into a network address for the console. It is the responsibility of the Transport developer to inform network managers of how to store this address. For IPX, AppleTalk, and OSI, these standards have been specified in RFCs (Request For Comments). These documents are available on-line off of the Internet and are maintained in various repositories and formats by the IETF.
  3512. Further Reference:
  3513. •    MacSNMP Programmer’s Guide
  3514. •    Shared Library Manager Programmer’s Guide
  3515. •    RFC 1157, A Simple Network Management Protocol (SNMP)
  3516. •    RFC 1155, Structure and Identification of Management Information for TCP/IP-based Internets
  3517. •    RFC 1419, SNMP over AppleTalk, Internet Proposed Standard
  3518. •    Macintosh System MIB
  3519. NW 23 - Routes From the Source
  3520. Networking    
  3521. Written by:    Tim Enwall and Rich Kubota    January 1992
  3522. This Technical Note discusses source routing and its possible implementation in token ring link layers.
  3523. Introduction
  3524. “AppleTalk,” in the words of Gursharan Sidhu, “is a network system.” As such, it provides for multiple types of media and data links, and token ring is one such data link.
  3525. Source routing refers to a process on token ring networks where the source of a packet indicates, to any bridges between the source and the destination, the route a packet must take to get from the source to the destination. The destination also uses this same route to transmit the response packet back to the proper place. The presence of routing information is indicated by a 1 in the most significant bit (MSB) of source address (SA) filed in the media access control (MAC) header. For nodes on the same ring, note that routing information is unnecessary.
  3526. Broadcast packets on a token ring always have their routing information bit turned on (Figure 1), indicating to bridges between the source and destination nodes that the route is to be inserted into the packet. For non-broadcast packets, each source node (SN) determines whether routing information is necessary, and hence either puts a 1 into the MSB of the source address and appends the routing control field, or it doesn’t. If the source routing bit is set to one, the routing information field (RC) is inserted between the source address (SA) field and the information field. With the source routing bit set to 0, the information field would immediately follow the source address (SA) field.
  3527. Each bridge puts its adjoining segment number into the next available SN field in the routing information field. Thus, a destination node could receive multiple packets from multiple bridges, and thus have several routes back to the source.
  3528. Note: The term broadcast  here refers to link-level broadcasts. This is not to be confused with AppleTalk broadcasts to the AppleTalk address $FF. These types of broadcasts are destined only for AppleTalk nodes on the link, not necessarily all nodes on the link.)
  3529. Figure 1  Routing Information and Routing Control Fields
  3530. Types of Broadcasts
  3531. At present, packets can be broadcast in one of three ways. The type of broadcast is defined by three bits in the routing control field of the routing information field (see Figure 1).
  3532. The types of broadcasts are as follows:
  3533. 100    All-routes broadcast, non-broadcast return. Broadcast packets of this type will travel along any possible path to the destination; thus the number of packets received at the destination will equal the number of routes to the destination node. Packets coming back to the source will travel along the same route, in reverse order, as they did going to the destination.
  3534. 110    Single-route broadcast, all-routes broadcast return. Broadcast packets of this type will travel along a single route, passing through designated bridges to the adjoining segment. Packets coming back to the source can possibly travel along multiple paths to reach the source; thus, the first packet received back at the source will indicate the best route between the destination and the source. A network administrator will set up the designated bridge as one that will forward this kind of broadcast. (Note that rev F of the TMS380 Adapter Chipset User's Guide Supplement, which describes these bits on page 7-4, incorrectly documents the bits, 111, to this type of broadcast.)
  3535. 111    Single-route broadcast, non-broadcast return. Broadcast packets of this type will travel along a single route, passing through designated bridges to the adjoining segment. Packets coming back to the source will travel along the same route, in reverse order, as they did going to the destination. A network administrator will set up the designated bridge as one that will forward this kind of broadcast. (Note that rev F of the TMS380 Adapter Chipset User's Guide Supplement, which describes these bits on page 7-4, incorrectly documents the bits, 110, to this type of broadcast.)
  3536. For directed transmissions between several bridges, the broadcast bits are 000. This indicates that the route is already present in the segment numbers, and the packet travels in a directed manner to the destination.
  3537. Source Routing on Apple’s TokenTalk Card
  3538. Apple’s TokenTalk Card is built upon the Macintosh Coprocessor Platform. Much of the TokenTalk software consists of dynamic A/ROSE tasks running on the card. Developers can use the services of TokenTalk Prep (documentation of which is available on the TokenTalk NB Programmer’s Guide), and the actual source routing is done with a SNAPXmit. SNAPXmit does the exact same thing as LLCXmit, but it doesn’t do source routing for you, nor do you have to specify a service access point (SAP).
  3539. Essentially, we have two types of packets to transmit: broadcast packets and individual directed packets.
  3540. For broadcast packets, which include functional address transmissions, group address transmissions, and all-stations broadcast transmissions, we add source routing information. For TokenTalk, the broadcast type is all-routes broadcast, non-broadcast return.
  3541. For individual directed packets, we have to determine if the destination is on our ring or not. If it is not then we must append the routing information to the packet. Where does the route come from? If we’ve been smart, we’ve been gathering routes from any broadcast packet we receive, and saving them away. We want to have a couple of tables on which to store the information: a table that maps destination nodes to ring numbers (segment numbers), and a table that maps ring numbers to routes. If we are asked to transmit an individual packet, we simply look up the destination ring number (compare it with our own ring number to determine whether routing information is necessary) and then look up the route for the ring we just looked up. Once we have a match, we just append the routing information and transmit the packet. Everything’s hunky- dory.
  3542. “But,” you ask, “what if I don’t have the route?” That is, what if there’s no ring number mapped to the destination address? You'll have to find the best route and then send it along. We do this by queuing the original request momentarily, packing up a Logical Link Control (LLC) test command packet, putting the desired destination address into the packet, and setting the broadcast type to “single-route broadcast, all-routes broadcast return.” This means we’ll get back (potentially, if there’s more than one route) many responses with routes in them. Hopefully the first such packet we receive will indicate the best route because it took the shortest amount of time to reach us.
  3543. Now, you’re probably asking yourself: “What did you mean when you said, ‘If we’ve been smart, we’ve been gathering routes from any broadcast packet we receive’?” Even better, every TokenTalk packet broadcast at the link layer will have this source routing information in it. Therefore, every TokenTalk packet will contain the route back to the source and we can “glean” this information and store it in our tables. This is where the direction bit comes in handy. If the direction bit is 1, then the furthest segment is the last segment number in the routing information field, that is, the rightmost. Conversely, if the direction bit is 0, then the furthest segment is the first segment number in the routing information field, that is, the leftmost. This furthest segment indicates the ring number the source is actually on, and we can add this source ring number to our table. We can also add (or update) our ring number to route table.
  3544. “What if the entries in this table just sit around—potentially after a node is no longer reachable?” That’s a good question. Again, we’ll use a common practice for such tables: each entry in our table should have some “age” associated with it, and when the “age” gets too old, we delete the entry from our table. The worst thing that can happen from such a deletion is we’ll have to go through the route discovery process again.
  3545. Conclusion
  3546. Source routing is necessary for any token ring link to function. Thus, hopefully, you have a clear recipe here for implementing that functionality in your code.
  3547. Further Reference:
  3548. •    TokenTalk NB Programmer’s Guide,  Chapter 2, “Source Routing Support”, APDA, M0827LL/A
  3549. •    IBM Token-Ring Network Architecture Reference, Chapter 3, “MAC Frame Format”, IBM Corporation, SC30-3374--01
  3550. •    TMS380 Adapter Chipset User's Guide, Texas Instruments, SPWU001D
  3551. •    TMS380 Adapter Chipset User's Guide Supplement, Chapter 7, Texas Instruments, SPWU003
  3552. •    J. Scott Haugdahl: Inside the Token-Ring, Chapter 3, “Standards and Protocols”, Architecture Technology Corporation, 1986
  3553. NW 25 - TokenTalk Programmer’s Guide Update 
  3554. Networking    
  3555. Written by:    Rich Kubota    July 1992
  3556. This Technical Note presents the additions and changes to the TokenTalk Programmer’s Guide and the latest information with regard to software development for the Apple Token Ring NB and Token Ring 4/16 NB network cards.
  3557. Introduction
  3558. With the release of the Token Ring 4/16 NB Card, the TokenTalk driver software was modified to support the Multivendor ADEV Architecture. This architecture is described in detail in M.NW.AppleTalk2, “What’s New With AppleTalk Phase 2.” This Tech Note presents topics specific to TokenTalk as presented in the TokenTalk Programmer’s  Guide. 
  3559. The first section, “TokenTalk Prefs File,” discusses changes to the 'llcp' resources of the TokenTalk Prefs file. The Options field is now used to store the speed setting for the card and to determine whether the Early Token Release feature is to be supported.
  3560. The next section, “TokenTalk Prep Services,” describes the new TokenTalk Prep utility routines for getting and setting the default and boot parameters for an Apple MCP (Macintosh Coprocessor Platform) based token ring network card.
  3561. Getting the Latest TokenTalk Software
  3562. For testing purposes, the latest version of AppleTalk and related software can be installed by using the Network Software Installer, available on the latest Developer CD, on AppleLink on the Developer Services Bulletin Board, and on the Internet through anonymous FTP to ftp.apple.com (130.43.2.3). The Network Software Installer includes all necessary components for the TokenTalk driver software including A/ROSE.
  3563. TokenTalk Prefs File
  3564. This section  discusses the changes to the 'llcp' resource and supplements the material presented in Chapter 6, “Download and Initialization” of the Programmer’s Guide. The primary change to the resource concerns the 'Options' field, and the increase of the default MaxFrame size setting. The TokenTalk Prefs file will be found in the Preferences folder in system software version 7.0 and later, and in the System Folder for version 6.0.x. The file contains the preferred Logical Link Control (LLC) initialization parameters for a card. These parameters are stored in 'llcp' resources with resource IDs corresponding to the slot number of the smart Token Ring Card to be supported. These initialization parameters override the default settings provided in the TokenTalk Prep file. For example, if the user selects a smart Token Ring Card in NuBus slot 9 to be used, the TokenTalk Prep routines will search for 'llcp' resource ID 9 in the Prefs file. If the resource is not found in the Prefs file, the default 'llcp' parameters in the Prep file will be used.
  3565. The format of the 'llcp' is as follows:
  3566. typedef struct
  3567. {
  3568.     long              FAddr;            /* Functional address */
  3569.     long              GAddr;            /* Group address */
  3570.     long              Options;          /* See below */
  3571.     void              (*Listener)();    /* Pointer to SAP 0 listener, always 0 in                         resource */
  3572.     unsigned short    MaxFrame;         /* Maximum frame size */
  3573.     unsigned short    StationMax;       /* Maximum number of stations */
  3574.     unsigned short    BufferSize;       /* Buffer size within chipset */
  3575.     unsigned char     SAPMax;           /* Maximum number of SAPs */
  3576.     unsigned char     GSAPMax;          /* Maximum number of GSAPs */
  3577.     unsigned char     GSAPMemberMax;    /* Maximum number of members in a group SAP                         */
  3578.     unsigned char     TxBufs;           /* Number of buffers in transmit list */
  3579.     unsigned char     RxBufs;           /* Number of buffers in receive list */
  3580.     unsigned char     IntMsgs;          /* Number of interrupt message buffers */
  3581.     unsigned char     TimerT1_1;        /* Default group 1 response timer */
  3582.     unsigned char     TimerT2_1;        /* Default group 1 receive acknowledge timer                         */
  3583.     unsigned char     TimerTI_1;        /* Default group 1 inactivity timer */
  3584.     unsigned char     TimerT1_2;        /* Default group 2 response timer */
  3585.     unsigned char     TimerT2_2;        /* Default group 2 receive acknowledge                         timer*/
  3586.     unsigned char     TimerTI_2;        /* Default group 2 inactivity timer */
  3587.     unsigned char     TxBufMin;         /* Transmit buffers minimum */
  3588.     unsigned char     TxBufMax;         /* Transmit buffers maximum */
  3589.     unsigned char     NodeAddr[6];      /* Node address (0 to use burned-in address)                         */
  3590.     unsigned char     ProdID[18];       /* Product ID string */
  3591.     unsigned char     LLCName[32];      /* IPC name of this LLC (C string) */
  3592. } TRInit;
  3593. Options Field
  3594. TokenTalk version 2.4 makes use of the low three bits of the Options field as follows:
  3595. Bits 0 and 1 are used to indicate the current speed setting for the Token Ring 4/16 NB Card as follows:
  3596.     4 Mbits/sec    bit 0 -> ON,  bit 1 -> OFF
  3597.     16 Mbits/sec    bit 0 -> OFF, bit 1 -> ON
  3598. Bit 2 is used to flag use of the “Early Token Release” feature : 0 -> ON, 1 -> OFF.  This feature only applies to the TokenRing 4/16 NB card when operating at 16 Mbits/sec.
  3599. For speed switchable cards, the TokenTalk Phase 2 ADEV checks whether bits 0 and 1 have been set correctly when the user selects a smart card in the network cdev. If neither bit is set, the user is presented with a dialog box allowing the user to select the desired speed. The Token Ring cdev also checks these bits to determine which radio button to select for speed switchable smart cards. For the TokenTalk NB card, which is nonswitchable, the bit settings are insignificant, and the speed is assumed to be 4 Mbits/sec.
  3600. Default Maximum Frame Size
  3601. The default MaxFrame size setting in TokenTalk version 2.3 and earlier was 1536 bytes. With TokenTalk Prep version 2.4, the maximum default frame size has been increased to 4464 bytes. The maximum frame size setting limits the amount of memory set aside by the token ring chipset for each receive buffer.  If on an LLCOpenSAP or LLCOpenStation call, the MaxIField setting is greater than the MaxFrames value specified in the 'llcp' resource, then the MaxFrame value is used instead.
  3602. TokenTalk Prep Services
  3603. TokenTalk Prep version 2.4 provides several new services to developers for determining and setting boot time parameters, and determining whether the Token Ring Card is speed switchable. The following new selectors are implemented in the TokenTalk Prep 'ttut' utilities. This section supplements the material presented in Chapter 6, “Download and Initialization,” of the Programmer’s Guide. 
  3604. TTGetDefaultParms    10    Return default TRInit parameters.
  3605. TTGetBootParms    11    Return TRInit parameters to use at the next boot time.
  3606. TTSetBootParms    12    Save TRInit parameters to the TokenTalk Prefs file.
  3607. TTSpeedSwitchable    13    Determine if the token ring speed is switchable or not.
  3608. TTGetDefaultParms
  3609. The TTGetDefaultParms function returns a pointer to the default LLC initialization parameters from the TokenTalk Prep file 'llcp' resource. The second parameter to this request is a mask of the slot to operate on. This mask must have only a single bit set since the default parameters for a single card can be returned. The result of this operation is a 32-bit NuBus address, a pointer to a structure of type TRInit, if nonzero. The pointer must be disposed of when finished.
  3610. This function calls a card-specific routine to fill in the address field with that of the burned-in address from the card, the Product ID string, and the LLCName as a C string. A result of 0 indicates that 
  3611.     1.  there is no supported card in the specified slot, 
  3612.     2.  more than one card was specified,
  3613.     3.  the 'llcp' resource could not be found, 
  3614.     4.  or a memory allocation error occurred.
  3615. The following call returns the default LLC parameters for a smart Token Ring Card in NuBus slot C:
  3616.     result = (*UtilPtr) (TTGetDefaultParms, 1<<0xC);
  3617. TTGetBootParms
  3618. The TTGetBootParms function returns a pointer to the LLC initialization parameters to be used on the next boot of the designated card. As with the TTGetDefaultParms function, the second parameter to this request is a mask of the slot to operate on. This mask must have only a single bit set. This function first checks whether a card-specific 'llcp' resource for the card exists in the TokenTalk Prefs file; otherwise the default parameters specified in the 'llcp' resource in the Prep file are returned. The result of this operation is a 32-bit NuBus address, a pointer to a structure of type TRInit, if nonzero. The pointer must be disposed of when finished.
  3619. This function calls a card-specific routine to fill in the address field with that of the burned-in address from the card, the Product ID string, and the LLCName as a C string. A result of 0 indicates that 
  3620.     1.  there is no supported card in the specified slot, 
  3621.     2.  more than one card was specified,
  3622.     3.  an 'llcp' resource could not be found, 
  3623.     4.  or a memory allocation error occurred.
  3624. The following call returns the default LLC parameters for a smart Token Ring Card in NuBus slot D:
  3625.     result = (*UtilPtr) (TTGetBootParms, 1<<0xD);
  3626. TTSetBootParms
  3627. The TTSetBootParms function stores LLC initialization parameters to the TokenTalk Prefs file. The function takes as input a pointer to a structure of type TTSetBP as the second parameter. The structure type, TTSetBP, is described below. The function searches for the Prefs file in the Preferences folder or creates the file if one does not exist. It then writes the initialization parameters to an 'llcp' resource using the slot number passed in the TTSetBP parameter block. If an 'llcp' resource already exists under the ID of the slot number, the old resource is replaced by the new parameters. The function returns TRUE if the parameters are successfully stored, or FALSE if unsuccessful. Under system software version 6.0.x, the Prefs file is searched for or created in the Blessed Folder.
  3628. The newly stored LLC initialization parameters will be used the next time the card is started. To use the burned-in address on the card as the node address of the card, set all bytes of the NodeAddr field to 0.
  3629. A result of 0 indicates that 
  3630.     1.  a memory allocation error occurred,
  3631.     2.  a problem occurred opening the Preferences folder or file,
  3632.     3.  the Prefs file could not be created,
  3633.     4.  or Resource Manager error occurred.
  3634. typedef struct
  3635. {
  3636.        long     SlotNo;    /* Slot number to save */
  3637.        TRInit   *TRPtr;    /* Pointer to a TRInit data structure described above                     */
  3638. } TTSetBP;
  3639. The following demonstrates the use of the TTGetBootParms utility to set the boot parameters for a smart Token Ring Card in NuBus slot E:
  3640.       TRInit  myTRRec;
  3641.        TTSetBp  my SetBP
  3642.        void  *SetMyTRInitRec(TRInit &myTRRec);
  3643.        SetMyTRInitRec(myTRRec); /* set LLC parameters */
  3644.        mySetBP.SlotNo = 0x0E;
  3645.        mySetBP.TRPtr = myTRRec;
  3646.        result = (*UtilPtr) (TTGetBootParms, &mySetBP, );
  3647. TTSpeedSwitchable
  3648. The TTSpeedSwitchable function returns true if the speed on the Token Ring Card can be switched, or false if not. This function does not indicate the current speed setting for the card. To determine the speed, check the Options field of the 'llcp' resource. If the two lowest bits, 0 and 1, are not set, then assume that the card supports only the 4 Mbits/sec speed. The second parameter to this request is a mask of the slot to operate on. This mask must have only a single bit set since the setting for only a single card can be returned.
  3649. The following call returns the default LLC parameters for a smart Token Ring Card in NuBus slot A:
  3650.     result = (*UtilPtr) (TTSpeedSwitchable, 1<<0xA);
  3651. Further Reference:
  3652. •    TokenTalk Programmer’s Guide, Apple Computer, Inc. (M0827LL/A)
  3653. •    M.NW.AppleTalk2
  3654. •    Macintosh Coprocessor Platform Developer's Kit, Apple Computer, Inc. (M0793LL/A)
  3655. NW 505 - AppleTalk Data Stream Protocol Q&As
  3656. Networking    
  3657. Revised by:    Developer Support Center    September 1993
  3658. Written by:    Developer Support Center    October 1990
  3659. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  3660. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  3661. AppleTalk Data Stream Protocol references
  3662. Date Written:  11/13/90
  3663. Last reviewed:  8/1/92
  3664. Where are the AppleTalk Data Stream Protocol (ADSP) calls documented?
  3665. ___
  3666. APDA has a product called “ADSP: AppleTalk Data Stream Protocol Development Kit” that gives you ADSP and the ADSP call descriptions. ADSP and ADSP interfaces can be found on the Developer CD and can be used for your development purposes. However, you’ll need to license ADSP through Apple Software Licensing (AppleLink: SW.LICENSE) before you ship your product. Calls are also documented in Chapter 32 of Inside Macintosh Volume VI.
  3667. If you want to use ADSP, then you should read ALL of the documentation. There are various tips and explanations that may be vital to your implementation of ADSP in your product. It is useful for transferring data between machines and provides built-in error checking to ensure that you do receive the data at the other end. For these reasons, you should read Inside AppleTalk, Chapter 12, Apple Data Stream Protocol, to make sure you utilize it to its fullest.
  3668. Sending broadcast packets to transmit data to multiple clients
  3669. Date Written:  11/19/90
  3670. Last reviewed:  6/14/93
  3671. How do I broadcast information over AppleTalk using the Communications Toolbox (CTB) and the AppleTalk Data Stream Protocol Development (ADSP) Tool or multiple access? I cannot find any significant information regarding broadcast or multiple access transmissions.
  3672. ___
  3673. There is no supported method to send broadcast packets to transmit data to multiple clients. The reason is that this method does not ensure the data was received by every client. It is possible to lose a packet on a network before it reaches a client even though it may reach the others. If this is the case then the data is lost forever for this client unless you resend the packet. This is highly inefficient and unreliable.
  3674. If you want to have multiple clients, then you’ll need to write your own server software that can handle multiple clients logged on simultaneously. The server will then need to keep a record of every connection and its corresponding transaction ID even though you will be sending the same information to each client; this is to ensure that each client receives the data. Following the ADSP protocol should be enough for you to implement this server/client connection and ensure that the data is reliably transmitted to each node.
  3675. ADSP closes connections on eClosed or eTearDown events
  3676. Date Written:  7/30/91
  3677. Last reviewed:  6/14/93
  3678. When I receive an eClosed or eTearDown ADSP connection event, do I have to close my end of the connection, or does ADSP close it automatically?
  3679. ___
  3680. When you get a eClosed unsolicited event, it means the other (remote) side of the ADSP connection sent a Close Connection Advice control packet and ADSP has closed the connection. It is purely advisory and does not require you to take any action. The Close Connection Advice control packet allows ADSP to close connections faster than just waiting for the connection to time-out due to the open timer expiring.
  3681. When you get a eTearDown unsolicited event, it means the network connection with other side of the ADSP connection was lost (the open timer expired) and ADSP has closed the connection. Again, it is purely advisory and does not require you to take any action.
  3682. The ADSP chapter of Inside AppleTalk (Chapter 12) might with help other questions you may have about ADSP in the future since it explains how ADSP works beneath the Macintosh implementation documented in Inside Macintosh Volume VI.
  3683. ADSP dspAttention and attention retransmit timer interval
  3684. Date Written:  9/16/91
  3685. Last reviewed:  6/14/93
  3686. I’m having problems with the AppleTalk Data Stream Protocol (ADSP) call dspAttention. Sometimes it takes several minutes for dspAttention to complete.I’ve tried using ADSP 1.5.1 with System 6.0.7 and ADSP 56, which ships as part of System 7.
  3687. ___
  3688. ADSP 1.5.1 (and ADSP 56) no longer uses the attnInterval field in the DSPParamBlock for the attention retransmit timer interval. Instead, the attention retransmit timer interval is based on the round-trip time of ADSP data packets. When a connection end is established, the attention retransmit acknowledged, the attention retransmit timer interval is adjusted for the connection speed. This mechanism works well when a connection end is established, an ADSP connection is opened, the connection is used, the connection is closed, and then the connection is eliminated.
  3689. A problem in this mechanism can surface when a connection end is established and is reused over and over for several ADSP connections. When a connection is closed and then a new connection is opened using the same connection end, the attention retransmit timer interval is not reset to the default starting value (the problem). Instead, some garbage value in memory is used. If the first ADSP attention packet or the acknowledgment packet returned for that attention packet is lost on the network, ADSP will use the “garbage” value for the attention retransmit timer interval and it could take several minutes for ADSP to retry sending the attention packet.
  3690. This has been fixed for versions of ADSP greater than version 56. With versions of AppleTalk 56 and earlier, the only workaround is to use a new connection end for every new ADSP connection requiring ADSP’s attention mechanism.
  3691. Using ADSP with AppleTalk for Apple’s VMS
  3692. Date Written:  5/3/89
  3693. Last reviewed:  6/14/93
  3694. I am trying to create a simple program to try ADSP (AppleTalk Data Stream Protocol) with AppleTalk for Apple’s VMS (version 2). I started the bridge process but got an access violation on the first call.
  3695. ___
  3696. You need to make three calls before you can call any other functions with AppleTalk for VMS. These calls are:
  3697.     ATK$INIT_ATALK
  3698.     ATK$INIT_PORT
  3699.     ATK$OPEN_PORT
  3700. Then you can use the other routines.
  3701. Appletalk Internet Router and Internet Protocol support
  3702. Date Written:  5/15/92
  3703. Last reviewed:  8/1/92
  3704. Does the Appletalk Internet Router support the routing of Internet Protocol packets, or Datagram Delivery Protocol-to-Internet Protocol translation?
  3705. ___
  3706. The AppleTalk Internet Router does not provide support for routing IP packets or the translation of IP packets encapsulated inside AppleTalk packets into IP packets.  It only supports the routing of AppleTalk packets between AppleTalk link layers such as LocalTalk, EtherTalk, and TokenTalk.  To route IP packets between, for instance, a LocalTalk network and an IP only backbone, you'll need to purchase a hardware router such as a Cayman Gatorbox or a Shiva Fastpath. Using one of these routers you can, using MacTCP, tunnel IP packets in AppleTalk packets by selecting the appropriate AppleTalk adev from within the MacTCP Control Panel. This will allow transfer of IP packets over the wire and the hardware routers will then strip the AppleTalk protocol, allowing IP packets to reach their destination over Ethernet. In addition, these routers usually support tunneling AppleTalk within IP packets (IPTalk).
  3707. If both the host computer running the TCP/IP protocol stack and the Macintosh you wish to connect from are on the same Ethernet wire, you can select Ethernet from the MacTCP Control Panel to bypass the encapsulation of IP packets within AppleTalk DDP packets.
  3708. ADSP session limits
  3709. Date Written:  7/21/92
  3710. Last reviewed:  6/14/93
  3711. What’s the absolute maximum number of ADSP sessions that a single Macintosh can have? What’s the largest client community that can be served at any given time?
  3712. ___
  3713. As documented in Inside AppleTalk 2nd Edition, page 4-5, dynamic sockets can range from 128-254. Therefore, when using ADSP you have 126 different dynamic sockets available for use as connection ends.
  3714. Note that you may have only one connection open between a pair of sockets. However, it is possible to have multiple connections open on the same socket, provided that the other end of each connection resides on a different socket. For example, socket 128 on machine B may have connections with socket 128 on machine C and socket 128 on machine D, but it may not have more than one connection with the same socket of a remote machine.
  3715. When a connection is established between two sockets, each connection end is assigned a unique connection ID value (ConnID). The ConnID is an unsigned integer. Therefore, it is theoretically possible to have 65,535 different connections on a single machine.
  3716. However, since each connection requires that you allocate a CCB data structure (242 bytes), you will most likely run out of memory long before this limit is reached. In addition, the more connections you have, the more traffic you will generate on the network since each connection is maintained internally by ADSP with probe control packets and connection timers (see Chapter 12 of Inside AppleTalk 2nd Edition for the details). On top of that, if each connection is transferring a lot of data, the burden of passing ADSP packets around will put an even greater strain on your machine and the network in general.
  3717. NW 510 - AppleTalk Filing Protocol Q&As
  3718. Networking    
  3719. Revised by:    Developer Support Center    September 1993
  3720. Written by:    Developer Support Center    October 1990
  3721. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  3722. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  3723. New Q&As in this Technical Note:
  3724. AFP error codes -5060,-5061, -5062, and -5063
  3725. AFP error codes -5060,-5061, -5062, and -5063
  3726. Date Written:  1/18/93
  3727. Last reviewed:  6/14/93
  3728. What’s AppleTalk error -5062? It seems to be an AppleTalk Filing Protocol error of sorts but I can’t find it documented anywhere.
  3729. ___
  3730. Error -5062 is an afpAlreadyMounted error. You’ll get it from the AppleShare external file system if you try to mount an AppleShare volume that’s already mounted with PBVolumeMount. The three PBVolumeMount-related functions were added to System 7 very late during development, so afpAlreadyMounted (-5062), afpBadDirIDType (-5060), afpCantMountMoreSrvrs (-5061), and afpSameNodeEr (-5063) never made it into the public interface files.
  3731. Further Reference:
  3732. Inside Macintosh Volume VI, pages 25-49 and 25-50
  3733. How an AFP volume’s allocation block size is calculated
  3734. Date Written:  8/15/91
  3735. Last reviewed:  8/16/91
  3736. The AppleTalk Filing Protocol (AFP) doesn’t appear provide a way to learn about the allocation block size of a server volume. So, how is the allocation block size determined on AFP server volumes? I noticed that the Macintosh Finder seems to calculate “size on disk” erratically for files on some AFP server volumes. Is that a related problem?
  3737. ___
  3738. All the workstation can get from an AFP server is the Bytes Total and Bytes Free (returned by FPGetVolParms and FPOpenVol), so the AFP workstation code estimates the value it uses in the allocation block size field (vcbAlBlkSiz) of the volume control block (VCB). The workstation code comes up with a value for vcbAlBlkSiz from the Bytes Total value returned to FPOpenVol when the volume is opened. The calculation used is:
  3739.     vcbAlBlkSiz := round((BytesTotal / (512 * 65536)) + 0.5) * 512;
  3740. This is the same value a local HFS volume would use. If an AFP server is not running on a Macintosh (and then, probably not using HFS), then this value may not be what the server platform is actually using. And yes, the Finder uses the allocation block size in its calculations to decide how much space is used by a file, so the “size on disk” may not exactly reflect the amount of disk space actually used.
  3741. Inside Macintosh Volume VI PBGetVolMountInfoSize typo
  3742. Date Written:  1/22/92
  3743. Last reviewed:  6/14/93
  3744. When I call PBGetVolMountInfoSize to get the size of an AppleShare volume’s mounting information record, the function returns with no errors but ioBuffer points to garbage instead of the size of an AFPVolMountInfo record.
  3745. ___
  3746. The problem you’re having with PBGetVolMountInfoSize is a typo in Inside Macintosh Volume VI on page 25-48. In that call, the ioBuffer field should be a pointer to a word (2-byte) size variable, not a long (4-byte) size variable.
  3747. AFP 2.0 FPRead NewLine Mask change
  3748. Date Written:  5/3/89
  3749. Last reviewed:  11/21/90
  3750. I’m confused about the changes to FPRead in AFP (AppleTalk Filing Protocol) version 2.0. How do I use the NewLine Mask?
  3751. ___
  3752. The difference between AFP 1.1 and AFP 2.0 as far as the NewLine Mask is concerned is that, in AFP 1.1, the only legal values of NewLine Mask are $00 and $FF, whereas in AFP 2.0, all values of NewLine Mask are allowed. The NewLine Mask is logically ANDed with a copy of each byte read. If the result matches the NewLine character, the read terminates. The NewLine character is returned as the last byte of data that was read from the fork.
  3753. NW 515 - AppleShare Q&As
  3754. Networking    
  3755. Revised by:    Developer Support Center    September 1993
  3756. Written by:    Developer Support Center    October 1990
  3757. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  3758. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  3759. New Q&As in this Technical Note:
  3760. Alternate User Authentication Methods (UAMs)
  3761. Determining AppleShare Admin password
  3762. CreateResFile calls and AppleShare drop folders
  3763. Updating aliases when File Sharing state changes
  3764. Alternate User Authentication Methods (UAMs)
  3765. Date Written:   3/9/93
  3766. Last reviewed: 6/24/93
  3767. Is there a sanctioned way to use PBVolumeMount to mount a volume with an alternate user authentication method (UAM)? I heard there’s an old document describing AppleShare UAMs.
  3768. ___
  3769. Alternate User Authentication Methods (UAMs) aren’t a supported feature of the AppleShare workstation software. The only documentation to ever come out of Apple concerning alternate UAMs is a draft proposal titled “Multiple User Authentication Methods for AppleShare” and it was written back in 1987. The thing to remember is that the document was a draft proposal; not final documentation for a tested mechanism in shipping product. Apple Developer Technical Support will not supply this document to developers who don’t have it.
  3770. Although the code for the alternate UAM mechanism described by that document is in the AppleShare workstation, it has never been fully implemented or tested in any version of AppleShare Workstation (including the AppleShare 3.0 Workstation); it has been only partially tested by some of the engineers that wrote that code. Because the code for alternate UAMs has never been officially tested or documented as a shipping product, Apple Developer Technical Support can’t officially support you in this area. On top of that, engineering doesn’t consider the alternate UAM mechanism part of any current project, so we (in DTS) have no project to submit bugs against. It is very likely that the code for the alternate UAM mechanism in the current AppleShare workstation will be removed at some point, so you should not rely on it in any of your programs.
  3771. Since alternate UAMs aren’t a supported feature of AppleShare workstation, new features added to the AppleShare workstation don’t support them, and other parts of the operating system don’t use them. So PBVolumeMount (which is implemented for AppleShare volumes by the AppleShare workstation’s external file system code) doesn’t support alternate UAMs, and the Alias Manager (which uses PBVolumeMount to mount AppleShare volumes) doesn’t know anything about alternate UAMs and has no way to support them.
  3772. Determining AppleShare Admin password
  3773. Date Written:   2/8/93
  3774. Last reviewed: 7/9/93
  3775. I mistyped an AppleShare file server’s administrative password. How can I retrieve it?
  3776. ___
  3777. We can’t provide the information you’ve requested since it is considered proprietary (for security reasons). If you’ve lost your admin password you’ll need to delete your current Users & Groups Data File. This is the only sanctioned way to reset your password. (If you have a duplicate Users & Groups file on another server, you can copy this file over and change the password accordingly.)
  3778. CreateResFile calls and AppleShare drop folders
  3779. Date Written:   4/28/93
  3780. Last reviewed: 7/2/93
  3781. Why does calling FSpCreateResFile return an afpAccessDenied error (in ResErr) when the destination folder is an AppleShare drop folder?
  3782. ___
  3783. Using any of the CreateResFile calls in a drop box is a useless exercise. Here’s why: The access privileges within a drop box are very limited write-only access. This lets you create new files and then perform a small set of operations on the file while it’s empty (no bytes in either the data or the resource fork of the file). So, while the file is empty, you can open it (either fork) with write-only access (PBHOpenDeny or PBHOpenRFDeny), and write the file’s attributes (PBHSetFInfo or PBSetCatInfo), including Desktop Manager comments. Once either fork has a single byte of data written to it, you can no longer open or change the file’s attributes. This makes it possible to copy a file into a drop folder, but not to manipulate or delete a file (containing data) that’s already in the drop folder. You can also move a file or directory into a drop folder if that file or directory is already on the same server volume.
  3784. So, when you call CreateResFile on a drop folder, a new file is created and data is added to the resource fork of the file. Since the file now has data in one of the forks, you cannot open the file or change any of the file’s attributes. FSpCreateResFile fails because after performing the CreateResFile operation that writes data into the resource fork, it attempts to set the file’s attributes (creator, fileType, and scriptTag).
  3785. For a quick explanation of drop folder access privileges and rules, see the Macintosh Technical Note “Creating Files Inside an AppleShare Drop Folder” (Files 18). For a complete explanation of what AFP access privileges you need to perform specific operations on an AppleShare (AFP) server, see the section “Directory Access Control” in Inside AppleTalk starting on page 13-31.
  3786. Updating aliases when File Sharing state changes
  3787. Date Written:   2/4/93
  3788. Last reviewed: 7/2/93
  3789. We create an alias for a file when File Sharing is off, so the alias doesn’t contain server and zone information. Then we turn on File Sharing and resolve the alias. The file, of course, is found but the alias isn’t marked for an update. Shouldn’t it be updated?
  3790. ___
  3791. According to Inside Macintosh: Files, wasChanged is set to TRUE only on 
  3792. aliases created by NewAlias (not NewAliasMinimalFromFullPath or NewAliasMinimal) when it sees that key information has changed. The key information is:
  3793. • name of the target
  3794. • directory ID of the target’s parent
  3795. • file ID or directory ID of the target
  3796. • name and creation date of the volume on which the target resides
  3797. Since none of that changes when you turn File Sharing on or off, the wasChanged flag isn’t set to TRUE. If you’re really worried about it, just call UpdateAlias every time you use the alias (unless you think this would be a major performance hit). Or maybe you should update it only if you notice that it doesn’t have server information and the server is now turned on (to check for this, call PBHGetVolParms and check the bHasPersonalAccessPrivileges bit).
  3798. Macintosh AppleShare client version details
  3799. Date Written:  12/18/92
  3800. Last reviewed:  3/1/93
  3801. System 7.0.1 doesn’t seem to correctly display (or display at all) login (greeting) messages from an AppleShare server. System 7.1 works fine. Is this a known problem, and is there anything we can do do get the login messages to show up?
  3802. ___
  3803. Not all Macintosh AppleShare clients support server messages (including the greeting messages). Every version of the Macintosh AppleShare client released since AppleShare 3.0 has supported server messages. If you install the AppleShare client version 3.0, 7.1 or 3.0.1 on System 7.0, 7.0.1 with or without System 7 Tune-up, you’ll get server greeting messages.
  3804. Here’s a list of Macintosh AppleShare client versions in the order they were released (notice that they aren’t in version order). We’ve listed the important changes made to each version and listed system software compatibility. (As you might suspect, DTS doesn’t have a complete list of all minor changes made to every version.)
  3805. AppleShare Client version:  2.0
  3806. Shipped with:               System 6.0.x and AppleShare 2.0
  3807. System Software versions:   6.0.x
  3808. Maximum AFP version:        2.0
  3809. Features:                   Supports AFP 2.0
  3810. AppleShare Client version:  7.0
  3811. Shipped with:               System 7.0
  3812. System Software versions:   7.0
  3813. Maximum AFP version:        2.1
  3814. Features:                   Supports required AFP 2.1 features only. Adds
  3815.                             support for these new File Manager functions:
  3816.                                PBCreateFileIDRef
  3817.                                PBDeleteFileIDRef
  3818.                                PBResolveFileIDRef
  3819.                                PBExchangeFiles
  3820.                                PBCatSearch
  3821.                                PBGetVolMountInfoSize
  3822.                                PBGetVolMountInfo
  3823.                                PBVolumeMount (no volume password support)
  3824. AppleShare Client version:  7.0.1
  3825. Shipped with:               System 7.0.1
  3826. System Software versions:   7.0 or 7.0.1
  3827. Maximum AFP version:        2.1
  3828. Features:                   No changes from version 7.0
  3829. AppleShare Client version:  3.0
  3830. Shipped with:               AppleShare 3.0
  3831. System Software versions:   System 6.0.4 through 6.0.8, System 7.0 and 7.0.1
  3832. Maximum AFP version:        2.1
  3833. Features:                   Added support for server greeting messages.
  3834.                             Patched the System 6 File Manager to support
  3835.                             these File Manager functions:
  3836.                                PBGetVolMountInfoSize
  3837.                                PBGetVolMountInfo
  3838.                                PBVolumeMount
  3839.                             PBVolumeMount now supports volume passwords.
  3840. AppleShare Client version:  7.1 and 3.0.1
  3841. Shipped with:               System 7.1 and AppleShare 3.0.1
  3842. System Software versions:   System 6.0.4 through 6.0.8, System 7.0, 7.0.1,
  3843.                             and 7.1
  3844. Maximum AFP version:        2.1
  3845. Features:                   Changes made for international support.
  3846. Auto-mounting AppleShare 3.0 volumes when a Greeting is enabled
  3847. Date Written:  6/5/92
  3848. Last reviewed:  3/1/93
  3849. Our program calls PBVolumeMount using MPW 3.2.2 interfaces to auto-mount FileShare and AppleShare servers when performing unattended backups, but if an AppleShare 3.0 server has a Greeting, the backup cannot proceed until the Greeting is dealt with. Is there a way to auto-mount these volumes which suppresses the Greeting?
  3850. ___
  3851. To mount a volume with PBVolumeMount and disable the greetings, you need to set bit 0 in the flags field of the AFPVolMountInfo record. The flags field was marked reserved in Inside Macintosh Volume VI because the greeting message feature had yet to be released when Volume VI was written. The Inside Macintosh: Files book (the revised edition of Inside Macintosh) documents this flag bit.
  3852. One thing you should be aware of is an alias record to an AFP volume created by the Alias Manager stores the flags information. That is, if you mount a volume with greetings disabled, create an alias to the volume (or a file or directory on the volume), and then later mount the volume by resolving the alias, the greeting message will be disabled. If the volume is mounted with the flags word cleared, any aliases resolved with show greeting messages (if any).
  3853. Here’s a short sample application that mounts a volume with greeting messages disabled:
  3854. Program MountVolTest;
  3855. USES
  3856.   Types,
  3857.   Files;
  3858. CONST
  3859.   kNormalMountFlags = 0;
  3860.   kInhibitMsgFlags = 1;
  3861. TYPE
  3862.   Str8 = STRING[8];
  3863.   { I like the following record structure better than }
  3864.   { the AFPVolMountInfo struture in Files.p }
  3865.   MyAFPVolMountInfo = RECORD
  3866.     length: Integer; { length of this record }
  3867.     media: VolumeType; { type of media, always AppleShareMediaType }
  3868.     flags: Integer; { 0 = normal mount; 1 = no greeting messages }
  3869.     nbpInterval: SignedByte; { NBP interval ; 7 is a good choice }
  3870.     nbpCount: SignedByte; { NBP count ; 5 is a good choice }
  3871.     uamType: Integer; { 1 = 'No User Authent' (guest); }
  3872.                       { 2 = 'Cleartxt Passwrd'; }
  3873.                       { 3 = 'Randnum Exchange'; }
  3874.                       { 6 = '2-Way Randnum exchange' }
  3875.     zoneNameOffset: Integer; { offset-record start to zoneName }
  3876.     serverNameOffset: Integer; { offset-record start to serverName }
  3877.     volNameOffset: Integer; { offset-record start to volName }
  3878.     userNameOffset: Integer; { offset-record start to userName }
  3879.     userPasswordOffset: Integer; { offset-record start to userPassWord }
  3880.     volPasswordOffset: Integer; { offset-record start to volPassWord }
  3881.     zoneName: Str31; { server's AppleTalk zone name }
  3882.     serverName: Str31; { server name }
  3883.     volName: Str27; { volume name }
  3884.     userName: Str31; { user name (0 length = guest) }
  3885.     userPassWord: Str8; { user password (0 length = no user password) }
  3886.     volPassWord: Str8; { volume password (0 length = no volume password) }
  3887.     END;
  3888. VAR
  3889.   gUAMType: Integer;
  3890.   gZoneName: Str31;
  3891.   gServerName: Str31;
  3892.   gVolName: Str27;
  3893.   gUserName: Str31;
  3894.   gUserPassWord: Str8;
  3895.   gVolPassWord: Str8;
  3896.   FUNCTION SilentMountAFPVolume: OSErr;
  3897.     VAR
  3898.       theAFPInfo: MyAFPVolMountInfo;
  3899.       pb: HParamBlockRec;
  3900.   BEGIN
  3901.     WITH theAFPInfo DO
  3902.       BEGIN
  3903.         length := sizeof(MyAFPVolMountInfo);
  3904.         media := AppleShareMediaType;
  3905.         flags := kInhibitMsgFlags;
  3906.         nbpInterval := 7;
  3907.         nbpCount := 5;
  3908.         uamType := gUAMType;
  3909.         zoneNameOffset := ORD4(@zoneName) - ORD4(@theAFPInfo);
  3910.         zoneName := gZoneName;
  3911.         serverNameOffset := ORD4(@serverName) - ORD4(@theAFPInfo);
  3912.         serverName := gServerName;
  3913.         volNameOffset := ORD4(@volName) - ORD4(@theAFPInfo);
  3914.         volName := gVolName;
  3915.         userNameOffset := ORD4(@userName) - ORD4(@theAFPInfo);
  3916.         userName := gUserName;
  3917.         userPasswordOffset := ORD4(@userPassWord) - ORD4(@theAFPInfo);
  3918.         userPassWord := gUserPassWord;
  3919.         volPasswordOffset := ORD4(@volPassWord) - ORD4(@theAFPInfo);
  3920.         volPassWord := gVolPassWord;
  3921.       END;
  3922.     pb.ioBuffer := @theAFPInfo;
  3923.     SilentMountAFPVolume := PBVolumeMount(@pb);
  3924.   END;
  3925. BEGIN
  3926.   gUAMType := 1; { mount as guest }
  3927.   gZoneName := 'Dev Support Center (DTS)';
  3928.   gServerName := 'Briggs';
  3929.   gVolName := 'SevenOh';
  3930.   gUserName := ''; { guest }
  3931.   gUserPassWord := ''; { guest }
  3932.   gVolPassWord := ''; { no volume password }
  3933.   IF SilentMountAFPVolume <> noErr THEN
  3934.     DebugStr('couldn''t mount volume');
  3935. END.
  3936. Mounting volumes without using aliases
  3937. Date Written:  9/25/92
  3938. Last reviewed:  11/24/92
  3939. How can I mount a volume without using aliases? I get the mounting information, then attempt to mount the volume. However, the PBVolumeMount call returns an error code.
  3940. ___
  3941. The PBGetVolMountInfo, PBGetVolMountInfoSize, and PBVolumeMount functions are currently handled by only the AppleShare external file system (part of the AppleShare Chooser extension). Those functions are available on AppleShare volumes when the AppleShare Chooser extension is version 7.0 (system software versions 7.0 and 7.0.1), version 3.0 (AppleShare 3.0), or version 7.1 (System 7.1). The AppleShare Chooser extension version 3.0 can be installed on System 6 systems, and then the PBGetVolMountInfo, PBGetVolMountInfoSize, and PBVolumeMount functions can be used in System 6. Other file systems may support these functions in the future. The paramErr error code is returned when these functions aren’t available on a particular volume.
  3942. How to tell if someone else has your data file open
  3943. Date Written:  7/7/92
  3944. Last reviewed:  11/1/92
  3945. How can I tell if another person has my data file open? According to Inside Macintosh Volume IV (pages 148–149), PBGetFInfo will tell you if anyone has a file open by returning the first access path found in ioFRefNum, but if I have this file already open, it returns information about myself. I want to be able to tell if anyone else has it open.
  3946. ____
  3947. If the file is on a local volume, you can index through the open FCBs to find all open connections to the file. You’ll find your own connection in that list but since you know what your ioRefNum is, you can ignore that match. For example, the following function will tell you if someone else has the file specified by myRefNum open. With a small change, you could have it return the number of other open connections instead of TRUE or FALSE.
  3948. FUNCTION OthersHaveItOpen (myRefNum: Integer): Boolean;
  3949.    VAR
  3950.       err: OSErr;
  3951.       fcbPB: FCBPBRec;
  3952.       myName: Str255;
  3953.       myVRefNum: Integer;
  3954.       myDirID: LongInt;
  3955.       index: LongInt;
  3956.       fileName: Str255;
  3957.       found: Boolean;
  3958. BEGIN
  3959.    fcbPB.ioNamePtr := @myName;      { let PBGetFCBInfo fill in the name. }
  3960.    fcbPB.ioVRefNum := 0;            { look on all volumes. }
  3961.    fcbPB.ioRefNum := myRefNum;      { use myRefNum to get info. }
  3962.    fcbPB.ioFCBIndx := 0;            { use ioRefNum instead of ioFCBIndx. }
  3963.    err := PBGetFCBInfoSync(@fcbPB); { get the open file’s info. }
  3964.    IF err = noErr THEN
  3965.       BEGIN
  3966.          { save my file’s vRefNum and dirID for matching later. }
  3967.          { myName was filled in by PBGetFCBInfo call above. }
  3968.          myVRefNum := fcbPB.ioFCBVRefNum;
  3969.          myDirID := fcbPB.ioFCBParID;
  3970.          { index through the open files on the volume }
  3971.          index := 1;
  3972.          REPEAT
  3973.             fcbPB.ioNamePtr := @fileName;
  3974.             fcbPB.ioVRefNum := myVRefNum;
  3975.             fcbPB.ioRefNum := 0;
  3976.             fcbPB.ioFCBIndx := index;
  3977.             err := PBGetFCBInfoSync(@fcbPB);
  3978.             IF err = noErr THEN
  3979.                { see if there is a match that isn’t myRefNum }
  3980.                found := (fileName = myName) AND 
  3981.                         (fcbPB.ioFCBParID = myDirID) AND 
  3982.                         (fcbPB.ioRefNum <> myRefNum)
  3983.             ELSE
  3984.                found := FALSE;  { no matches on errors }
  3985.             index := index + 1; { next index position... }
  3986.          UNTIL found OR (err <> noErr);
  3987.          OthersHaveItOpen := found;
  3988.       END
  3989.    ELSE
  3990.       OthersHaveItOpen := FALSE; { we don’t even have it open! }
  3991. END;
  3992. On nonlocal volumes (AppleShare volumes), you can use PBHOpenDeny with the deny-read and deny-write permissions to ensure nobody else can open a file you have open. You can tell which volumes are nonlocal by calling PBHGetVolParms and looking at the value returned in the GetVolParmsInfo.vMServerAdr field. If that value is 0, the volume is local.
  3993. Unmounting volumes shared with Macintosh File Sharing
  3994. Date Written:  9/15/92
  3995. Last reviewed:  3/10/93
  3996. I tried to unmount a volume shared with Macintosh File Sharing from my program using the following steps: I shut down the file service with the SCShutDown server control call; I call SCPollServer to make sure the file service is really off (scServerState = SCPSJustDisabled); then, I call PBUnmountVol to attempt to unmount the volume. It didn’t work because PBUnmountVol fails with fBsyErr (-47). I broke on the _UnmountVol trap because the AppleShare PDS file, where the file server keeps the access privilege and share-point information for the shared volume, was open. Why is AppleShare PDS still open when I’ve turned the file service off? How can I close it and unmount the volume?
  3997. ___
  3998. SCPollServer returns the state of the file service, not the file server application (in this case, File Sharing Extension is the file server application). When SCPollServer returns a server state of SCPSJustDisabled, the file service is off; however, the file server application may or may not still be running. The AppleShare PDS file will eventually get closed before the file server application quits.
  3999. There’s an easy way to determine when the File Sharing application has quit (and thus when the AppleShare PDS file is closed): just use the Process Manager GetNextProcess and GetProcessInformation calls to find out when File Sharing Extension is no longer running. The File Sharing Extension application has a processType of 'INIT' and a processSignature of 'hhgg'. Here’s a function you can use to see if the File Sharing Extension application is running:
  4000. FUNCTION FileSharingAppIsRunning: Boolean;
  4001.   CONST
  4002.     FileSharingSignature = 'hhgg';  {Macintosh File Sharing}
  4003.   VAR
  4004.     err:      OSErr;
  4005.     myPSN:    ProcessSerialNumber;
  4006.     myPInfoRec:  ProcessInfoRec;
  4007. BEGIN
  4008.   myPSN.highLongOfPSN := 0;  {Start at beginning of process list}
  4009.   myPSN.lowLongOfPSN := kNoProcess;
  4010.   myPInfoRec.processInfoLength := sizeOf(ProcessInfoRec);
  4011.   myPInfoRec.processName := NIL;   {Don't need process name}
  4012.   myPInfoRec.processAppSpec := NIL; {Don't need process location}
  4013.   FileSharingAppIsRunning := FALSE; {Haven't found it yet}
  4014.   WHILE (GetNextProcess(myPSN) = noErr) DO
  4015.     IF GetProcessInformation(myPSN, myPInfoRec) = noErr THEN
  4016.       IF (myPInfoRec.processSignature = FileSharingSignature)
  4017.         THEN
  4018.         FileSharingAppIsRunning := TRUE;  {Found it}
  4019. END;
  4020. After shutting down the file service, your event loop will need to poll with FileSharingAppIsRunning because you must give the file server application processing time to close files, dispose of memory, and perform other shutdown operations. If you poll with FileSharingAppIsRunning without giving other processes time, File Sharing will never shut down.
  4021. Maximum volumes for file sharing
  4022. Date Written:  3/9/92
  4023. Last reviewed:  8/1/92
  4024. In the past I’ve been able to file share more volumes off my Macintosh SCSI storage devices than I can with System 7. Now I get an alert saying: “One or more items could not be shared because not all volumes are available for file sharing.” Please advise as to what the problem might be.
  4025. ___
  4026. Macintosh File Sharing will only prepare for sharing the first 10 volumes it sees (it enumerates the volume list with PBHGetVInfo). The volumes you can’t share will usually be the ones mounted last. The reason you used to be able to share another set of volumes probably has to do with some change you’ve made (like changing the boot volume or a volume’s SCSI ID number).
  4027. So, you’ve just hit the limits of File Sharing. The solution to your problem is to use AppleShare 3.0—it will share up to 50 volumes. File Sharing wasn’t intended to be the end-all in file servers; it was designed for individuals who want to occasionally share files with a small number of other users. Here are some limits to File Sharing that you should note:
  4028. •    The number of users and groups in the Users & Groups Data File is limited to 100 total. (The limit with AppleShare 3.0 is 8192 total.)
  4029. •    The number of users that can be logged in at one time is 10 (this doesn’t count the owner of the system, one remote connection is always reserved for the owner of the system). (The limit with AppleShare 3.0 is 120.)
  4030. •    The number of share points available for regular users is 10. (The limit with AppleShare 3.0 is 50.)
  4031. •    The number of sharable volumes (what the owner sees when he or she logs in remotely and what can be shared or partially shared) is 10. (The limit with AppleShare 3.0 is 50.)
  4032. AppleShare 3.0 also supports many other user (for example, server messages), security, and developer features (server control calls and the server event mechanism) not supported by Macintosh File Sharing.
  4033. AppleShare user limit
  4034. Date Written:  11/16/90
  4035. Last reviewed:  12/19/90
  4036. What is the maximum number of users that can be logged in to any one AppleShare file server? What can we do to increase the limit? Will upgrading to AppleTalk Phase II help? Is there an upgrade to the AppleShare 2.0.1 software?
  4037. ___
  4038. AppleShare currently has a limit of 50 simultaneous users. This is a limitation in the software and is not related to AppleTalk. Changing from AppleTalk Phase I to Phase II will not change anything. The next version of AppleShare might raise this limitation. We do not have any projected dates for a release of the next version of AppleShare. You may want to periodically check with APDA for any update or new release.
  4039. Maximum number of users supported by AppleShare for each CPU
  4040. Date Written:  5/3/89
  4041. Last reviewed:  11/21/90
  4042. What is the maximum number of users supported by AppleShare? Does this number change based on the type of CPU being used for the server?
  4043. ___
  4044. The following chart lists some current AppleShare limits (AppleShare 1.1, 2.0, and 2.01) which are based upon the chosen server platform and memory configuration. The limits that otherwise might be present on a workstation are still in effect, and are not affected by the workstation being logged in to an AppleShare server. These limits will change in the future.
  4045. Server machine is Macintosh Plus, SE, or II with 1 MB:
  4046.     Number of users: 25
  4047.     Number of locked ranges: 1000
  4048.     Number of open files: 80
  4049.     Number of volumes: 16
  4050. Server machine is Macintosh II with more than 1 MB:
  4051.     Number of users: 50
  4052.     Number of locked ranges: 2000
  4053.     Number of open files: 160
  4054.     Number of volumes: 16
  4055. X-Ref:
  4056. Macintosh Technical Note “AppleShare 1.1 and 2.0 Limits”
  4057. Macintosh file system active ranges
  4058. Date Written:  3/18/91
  4059. Last reviewed:  6/7/91
  4060. How many active ranges can a Macintosh application have on a shared file? If the answer is more than one, is the limit per application or per machine? If two ranges overlap, are they joined into one range? Can an application nest ranges? For example, if an application’s user performs an action that forces a record to be locked and later the application locks the full range of the file, does the initial record lock disappear?
  4061. ___
  4062. The only way to determine the limit is to hit the limit and get a NoMoreLocks error. The number of range locks supported is a limit of the server platform, and that limit is shared by all users of the server (at least it is with Apple’s AppleShare server software). With Apple’s server-based version of AppleShare, approximately 40 locks per user are allowed (for example, if the server allows 25 users, there are 1000 locked ranges total; if the server allows 50 users, there are 2000 locked ranges total; and with File Sharing running under System 7.0, approximately 20 locks are allowed per user). Other vendors may allow more or fewer locked ranges on their implementations of an AppleTalk Filing Protocol (AFP) server. Notice that the numbers given are per user, not per application. It’s assumed that a user probably won’t need more than a few locks at a time on a single file.
  4063. You cannot have range locks that overlap. You’ll get a RangeOverlap error from AFP. All the rules for range locking can be found in the AFP chapter of Inside AppleTalk (page 13-56). Additional information on AppleShare limits is available on the latest Developer CD Series disc.
  4064. The Macintosh Technical Note “Lock, Unlock the Range” covers several important details about PBLockRange and PBUnlockRange that are not in Inside Macintosh.
  4065. AppleShare open file limit
  4066. Date Written:  10/8/91
  4067. Last reviewed:  10/8/91
  4068. On an AppleShare 2.0 File Server platform, the only application that can access files outside of the Server Folder (that is, the System Folder) is the file server application. AppleShare Foreground applications (described in the Macintosh Tech Note “AppleShare Foreground Applications” are the only other applications that should be running on a server and they can only access files inside the Server Folder. All file forks (referred to as files from here on) opened by remote AppleShare workstations are opened by the File Server application.
  4069. The File Server application will open a file only one time. All access to that file from any number of workstations will use the single access path the File Server has opened. Only when all workstations have closed the file does the File Server really close the file on the server. So, that means only one FCB is used on the server per open file, even if 50 users have shared access to that file.
  4070. The File Server application handles all access control to an open file using the AppleTalk Filing Protocol (AFP) deny-mode permission model. The only reason a user won’t be able to open an access path to a file on a server is if another user has opened that file with a deny-mode that conflicts with the second user’s request, or the user does not have the access rights needed to open files in the file’s parent directory or directory ancestors. The AFP deny-mode permission model is described briefly in Inside Macintosh Volume V, File Manager Extensions in a Shared Environment, and in detail in the AppleTalk Filing Protocol chapter of Inside AppleTalk.
  4071. As noted in the Macintosh Tech Note “AppleShare 1.1 and 2.0 Limits,” the maximum number of open file forks on an AppleShare 2.0 server is either 80 on a 1 MB MC68000 server platform, or 160 on a server platform with more than 1 MB and a MC68020 or greater processor. That figure includes the number of files kept open by the system and the file server application. If an AppleShare Foreground application is running on the server (for example, the AppleShare Print Server), then any files it may have open count against the maximum, too. The same can be said for open desk accessories. This Tech Note currently doesn’t say anything about those files counting towards the limit. If the 160 (or 80) file limit is a problem, you can use the “Up Your FCBs” INIT to bump the number available up to the maximum (342) allowed by the File Manager. “Up Your FCBs” can be found on AppleLink in the Developer Support: Developer Technical Support: Hacks folder.
  4072. Software-selecting an AppleShare volume
  4073. Date Written:  10/23/90
  4074. Last reviewed:  2/20/91
  4075. Is there any source code available for mounting/unmounting AppleShare volumes?
  4076. ___
  4077. There are actually a couple of ways to select an AppleShare volume. You could use the Choose tool in MPW that accomplishes this, or you can do it with aliases under System 7. Other than the MPW tool, there is no other supported way of doing this under pre-7.0 systems; there are no current hooks to allow easy mounting of AppleShare volumes programmatically. It gets pretty nasty trying to figure out everything that is necessary to accomplish this, which is why people here pretty much stay away from this as well. Also, some low-level stuff may be proprietary, which is why the tool is supplied for developers. The Choose tool is described in the MPW docs. It should be pretty straightforward to use.
  4078. 2.0.1 PBHGetDirAccess and PutDirAccess restrictions
  4079. Date Written:  12/5/90
  4080. Last reviewed:  1/16/91
  4081. If a volume is connected to an AppleShare server, but is not an AppleShare volume, will the PBHGetDirAccess (and PutDirAccess) function work on it? Can an INIT on the server make these calls?
  4082. ___
  4083. For AppleShare 2.0.1, the INIT cannot make these calls on non-file server volumes. In future versions, the PBHGetDirAccess and PutDirAccess calls can safely be made on all volumes connected.
  4084. Server Move & Rename folder
  4085. Date Written:  12/5/90
  4086. Last reviewed:  6/14/93
  4087. A folder is created in the Server Folder called “…Move & Rename.” What is this and what are its contents? Should it be backed up? Are there any other temporary folders and files that might need to be backed up?
  4088. ___
  4089. It’s the “$01$02$03Move & Rename” folder that AppleShare 2.0.1 and future versions create for the two-step process of moving and renaming a file or a folder, a feature that is not provided via HFS. It should be backed up, but in general will not contain anything. (It has something in it only for a brief instant and only if the server has IBM PCs or some other computer that uses this call. Macintosh systems don’t.) It needs to be backed up for 2.0.1 so that the folder is there if the server is restored. (Otherwise, Admin will have to be run to create a new one, a somewhat disconcerting action to perform after completely restoring a file server.)
  4090. How to tell if application’s running on a server
  4091. Date Written:  12/5/90
  4092. Last reviewed:  1/16/91
  4093. What is the best way to determine if a Macintosh application is running on a server?
  4094. ___
  4095. For 2.0.1 you can test the longword at $B50. If it is 0 or -1, the server is not running. If it isn’t—that is, it’s a real address—then the server is either starting up, or is running. There might be a hook available in future versions of AppleShare that your process can hook into.
  4096. Detecting AppleTalk being closed down by user
  4097. Date Written:  12/12/90
  4098. Last reviewed:  6/14/93
  4099. How do I detect that a user has closed down my AppleTalk connection (by turning AppleTalk off from the Chooser or by changing network connections from the Network control panel)?
  4100. ___
  4101. The AppleTalk Transition Queue provides a means to determine when the AppleTalk drivers change status or when they might be closed in the very near future. The Transition Queue informs its clients (everyone who has asked to be added to the queue) each time the state of the .MPP driver changes state (opened or closed) or is about to change state.
  4102. The AppleTalk Transition Queue is documented in Inside Macintosh Volume VI, Chapter 32 (The AppleTalk Manager) and is also documented in the Macintosh AppleTalk Connections Programmer’s Guide, Chapter 3 (Calls to the LAP Manager), available from APDA. A sample AppleTalk Transition Queue routine is shown in Tech Note 311.
  4103. Purpose of AppleShare SP file
  4104. Date Written:  3/14/91
  4105. Last reviewed:  4/29/91
  4106. What is the file “AppleShare SP” and what does it do? The AppleShare File Server seems to run without it, and it reduces the alert sound to just a beep even when the server is not running on that computer. Is the file really needed?
  4107. ___
  4108. You do need the AppleShare SP INIT on your file server. The AppleShare SP (Small Patch) INIT is designed to correct a minor incompatibility between AppleShare 2.0x and the Sound Manager. The INIT forces the Macintosh to use the “Simple Beep” sound at all times. System 7.0 file sharing and future versions of AppleShare do not need the INIT.
  4109. Macintosh EOF in an AppleShare environment
  4110. Date Written:  3/18/91
  4111. Last reviewed:  6/10/91
  4112. I ran into the following when updating the logical end of file (EOF) of a shared file: Application A and Application B have access to a file under AppleShare. Each is using fsRdWrShPerm. When Application A changes the logical EOF, Application B doesn’t seem to notice that EOF has changed until Application B calls GetEOF. Is there a better way to make Application B aware of the change of logical EOF?
  4113. ___
  4114. You’ve made a correct assumption that the correct way to keep track of EOF in an AppleShare environment is to ask for it. When you open a file, the AppleShare workstation code translates the Macintosh operating system Open call to the AFP (AppleTalk Filing Protocol) FPOpenFork call, and sets the bits in the bitmap parameter to current length of the fork opened (in the case of Open, the data fork). It then uses THAT as the EOF for future operations unless it gets an update from the server. Because the server does not constantly update everyone who has the file open, you have to ask to find if another user (or application) has made a change. Just remember that using GetEOF will only get you the EOF at that instant in time. Someone else sharing the file could change EOF right after you check it.
  4115. The PBLockRange function can be used by an AppleShare aware application to prevent another user from appending data to a shared file while you are appending data. For example:
  4116.   paramBlock.ioRefNum := myFileRef;
  4117.   err := PBGetEOF(@paramBlock, FALSE); {get the current EOF}
  4118.   {check for errors in a real application}
  4119.   
  4120.   oldEOF := paramBlock.ioMisc; {save the current EOF}
  4121.   paramBlock.ioReqCount := -1; {$FFFFFFFF}
  4122.   paramBlock.ioPosMode := fsFromStart;
  4123.   paramBlock.ioPosOffset := oldEOF; {start range lock at current EOF}
  4124.   err := PCLockRange(@paramBlock, FALSE); {and lock the rest of the fork}
  4125.   {check for errors in a real application}
  4126.   
  4127.   {now you can append data to the file}
  4128.   
  4129.   paramBlock.ioRefNum := myFileRef;
  4130.   paramBlock.ioReqCount := -1; {$FFFFFFFF}
  4131.   paramBlock.ioPosMode := fsFromStart;
  4132.   paramBlock.ioPosOffset := oldEOF;
  4133.   err := PCUnlockRange(@paramBlock, FALSE); {unlock the locked range}
  4134.   {check for errors in a real application}
  4135. PBLockRange can also be used when you need to truncate a shared file. Locking the portion of the file you’re about to truncate prevents another user from using that portion during the truncation process. For example:
  4136.   paramBlock.ioRefNum := myFileRef;
  4137.   paramBlock.ioReqCount := -1; {$FFFFFFFF}
  4138.   paramBlock.ioPosMode := fsFromStart;
  4139.   paramBlock.ioPosOffset := theNewEOF; {start lock at truncation point}
  4140.   err := PCLockRange(@paramBlock, FALSE); {and lock the rest of the fork}
  4141.   {check for errors in a real application}
  4142.   
  4143.   paramBlock.ioMisc:= theNewEOF;
  4144.   err := PBSetEOF(@paramBlock, FALSE); {set the new EOF (truncate the file)}
  4145.   {check for errors in a real application}
  4146.   
  4147.   paramBlock.ioReqCount := -1; {$FFFFFFFF}
  4148.   paramBlock.ioPosMode := fsFromStart;
  4149.   paramBlock.ioPosOffset := theNewEOF;
  4150.   err := PCUnlockRange(@paramBlock, FALSE); {unlock the locked range}
  4151.   {check for errors in a real application}
  4152. The entire fork can be locked with:
  4153.   paramBlock.ioRefNum := myFileRef;
  4154.   paramBlock.ioReqCount := -1; {$FFFFFFFF}
  4155.   paramBlock.ioPosMode := fsFromStart;
  4156.   paramBlock.ioPosOffset := 0; {lock from the beginning}
  4157.   err := PCLockRange(@paramBlock, FALSE); {lock the whole fork}
  4158.   {check for errors in a real application}
  4159.   
  4160.   {do your thing}
  4161.   
  4162.   paramBlock.ioRefNum := myFileRef;
  4163.   paramBlock.ioReqCount := -1; {$FFFFFFFF}
  4164.   paramBlock.ioPosMode := fsFromStart;
  4165.   paramBlock.ioPosOffset := 0; {unlock from the beginning}
  4166.   err := PCUnlockRange(@paramBlock, FALSE); {unlock the whole fork}
  4167.   {check for errors in a real application}
  4168. Macintosh AppleShare versus file sharing capabilities
  4169. Date Written:  4/3/91
  4170. Last reviewed:  6/21/91
  4171. We are using the file sharing capabilities of Macintosh systems with System 7.0 to make them mini file servers. Where can information that details the features of both AppleShare and file sharing be found? We are considering using only file sharing in the office if it is capable of providing most of what AppleShare provides.
  4172. ___
  4173. Information on file sharing can be found in the System 7 Personal Upgrade Kit and in Inside Macintosh Volume VI, on your Developer CD Series disc. The maximum number of concurrent connections allowed on a Macintosh using file sharing is 10. The performance of an AppleShare file server (the standard kind of server) is approximately 25 percent better than a similar configuration of Macintosh computers acting as a file sharing server.
  4174. System 7 and AppleTalk Internet Router
  4175. Date Written:  9/17/91
  4176. Last reviewed:  11/25/91
  4177. We’ve tried to run the Apple Internet Router with our System 7 file sharing servers. There does not appear to be support for multiple networks. Is there some solution to this?
  4178. ___
  4179. The AppleTalk Internet Router and System 7 are compatible, with two exceptions: virtual memory and 32-bit addressing. You need to drag-install it instead of using the Installer. The Installer script on the router disk will put the parts of the router in the wrong place. Here are the steps to drag-install the router:
  4180. 1.    Drag the files Router, LocalTalk (Built-in), and LocalTalk (Modem) from the System Folder on the AppleTalk Internet Router disk to the closed System Folder on the disk where you want to install. System 7 will automatically put the Router file in the System Folder, and put the LocalTalk (Built-in) and LocalTalk (Modem) files in the Extensions folder in the System Folder.
  4181. 2.    Under System 7, open the System file on the AppleTalk Internet Router disk (double-click the System file). A window will open showing the desk accessories, fonts, and sounds that are part of that System file. Drag the Router desk accessory from that window to the closed System Folder on the disk where you want to install. System 7 will automatically put the Router desk accessory in the Apple Menu Items folder in the System folder.
  4182. 3.    Reboot.
  4183. That’s all there is to it.
  4184. X-Ref:
  4185. “System 7: Installing Internet Router 2.0,” AppleLink Tech Info Library
  4186. TMGetTermEnvirons envVersTooBig error
  4187. Date Written:  9/17/91
  4188. Last reviewed:  9/17/91
  4189. A call made to TMGetTermEnvirons returns -5502 or envVersTooBig. The call is made with a good terminal handle started from your TTY tool. What’s wrong? How do I fix it?
  4190. ___
  4191. When you call TMGetTermEnvirons, the TermEnvironRec that you hand it a pointer to must have initialized the version field with curTermEnvRecVers. The following will work properly:
  4192. void getTEnvirons(TermHandle aTerm)
  4193. {  ...
  4194.    TermEnvironRec tEnv;
  4195.    TMErr err;
  4196.    ...
  4197.    tEnv.version = curTermEnvRecVers;
  4198.    err = TMGetTermEnvirons(aTerm,&tEnv);
  4199.    /* check for errors, do whatever... */
  4200.    ...
  4201. }
  4202. This is consistent with most other Macintosh “get environment” calls such as SysEnvirons, and is documented (somewhat unclearly) at the top of page 113 in Inside the Macintosh Communications Toolbox.
  4203. Modifying a server volume’s backup date-time from a workstation
  4204. Date Written:  12/5/91
  4205. Last reviewed:  1/27/92
  4206. How can I change the backup date of a remote AppleShare volume? When I get the volume information with PBHGetVInfo (followed by a PBFlushVol), change the backup date field, and call PBSetVInfo, the date is changed in my local copy of the volume information, but when I unmount and remount the AppleShare volume, the original backup date is still there.
  4207. ___
  4208. On an AppleTalk Filing Protocol (AFP) file server, two of the volume date-time values, the volume creation date-time and the volume modification date-time, are managed solely by the server and can’t be changed by workstations. The third volume date-time value, the volume backup date-time, can be set by a workstation with only one AFP call, afpSetVolParms. However, the File Manager, through the Macintosh AppleShare external file system, does not give an application a way to make the afpSetVolParms call. That leaves only one way you can change a server volume’s backup date-time from a workstation: You’ll have to use the AppleTalk .XPP driver to access the server directly.
  4209. Using the .XPP driver to change the backup date-time involves these steps:
  4210. •    Open the .XPP driver and get the driver reference number.
  4211. •    Use the afpLogin variant of AFPCommand to start a session and log in to the server. If the “Randnum Exchange” or “2-Way Randnum Exchange” user authentication methods are used, you will receive an AuthContinue error (-5001) from the afpLogin call and you’ll have to follow up the afpLogin call with an afpLoginCont call (through AFPCommand again) to finish the log-in sequence.
  4212. •    Once you’re logged in to the server, you need make an afpGetSrvrParms call to get a list of volumes and to find out if the volume you’re interested in has a password associated with it.
  4213. •    Then you need to call afpOpenVol with the volume name (and password if there is one). You can have afpOpenVol give you the volume’s current backup date-time and other volume information if you set the appropriate bits in the bitmap parameter passed to afpOpenVol.
  4214. •    Now that you’re logged in to the server and have the volume opened, you can make an afpSetVolParms call to change the backup date-time.
  4215. •    After changing backup date-time, you need to close the volume with afpCloseVol, and then log off the server with afpLogout.
  4216. The .XPP driver’s AFP commands are described in Inside Macintosh Volume V in the AppleTalk chapter (pages V-524 through V-550). For a description of the AFP calls, user authentication methods, and other AFP information, you need to look in the AppleTalk Filing Protocol chapter of Inside AppleTalk. If you decide you want to really use the .XPP driver as described above and want to use the 2-Way Randnum Exchange user authentication method supported by System 7 File Sharing and AppleShare 3.0, contact DTS for a preliminary version of the AFP 2.1 specification that describes that new authentication method.
  4217. AppleShare Print Server 3.0 and AppleTalk self-send
  4218. Date Written:  2/28/92
  4219. Last reviewed:  2/28/92
  4220. When I issue a PAPWrite from my application to the AppleShare Print Server 3.0 running on the same Macintosh, PAPWrite locks up in a tight loop. If I send to a LaserWriter or the AppleShare Print Server 3.0 running on a different Macintosh system, all works well. The LaserWriter Font Utility 7.0 behaves the same as my application: It works if the spooler is remote and locks up if the spooler is local.
  4221. ___
  4222. You’re probably calling PAPWrite and then not giving up any system time needed by the print server to process the data you sent to it. That just doesn’t work in the self-send environment. For example, the following won’t work:
  4223.     PAPWrite(refNum, writeBuff, dataSize, eof, compState);
  4224.     WHILE compState = 1 DO
  4225.         ; { do nothing -- wait for PAPWrite to complete }
  4226. What your application should do is drop back into its event loop after making the PAPWrite call and then poll compState to see when the PAPWrite completes. By calling WaitNextEvent from your event loop, your application gives the print server application the time it needs to receive and process the data you sent to it.
  4227. The LaserWriter Font Utility wasn’t designed to work with print servers and will exhibit the same problem your application is experiencing.
  4228. System 6 & 7 Chooser AppleShare differences
  4229. Date Written:  2/28/92
  4230. Last reviewed:  2/1/93
  4231. What’s the limit on the number of servers displayable in the Chooser as well as the maximum number of AppleShare mount points per server? Are the System 7 limits the same as for System 6?
  4232. ___
  4233. Most System 6 Chooser limitations have been eliminated with the System 7 Chooser. Here’s how each version operates:
  4234. System 6 Chooser: 
  4235. The 6.0 Chooser’s LookupName call to find AppleTalk entities is made asynchronously where retBuffPtr points to a 512-byte buffer and maxToGet = 32 (this is the 32-device limit per device type you may have heard of). The important thing to note here is the return buffer size (512 bytes). For example, if you are looking for AppleShare servers in your own zone (the “*” zone), the number of overhead bytes per NBP tuple returned will be 16 (5 for the entity address, 10 for the string “AFPServer”, and 2 for the string “*”). If there were 20 servers in your zone, 340 bytes of the 512-byte buffer are used before you start counting the space used by the server names. That leaves 172 bytes for the names or around 8 characters per name (1 length byte plus 8 characters). If the average server name is longer than that, there won’t be enough room to collect all of the NBP replies and one or more servers won’t show up in the list.
  4236. Once a server is selected and the user is authenticated, the AppleShare 2.0 RDEV uses afpGetSrvrParms to ask for the list of server volumes. The AppleShare 2.0 RDEV uses a 512-byte buffer for the replies. After the overhead used by the AppleTalk protocol headers, that’s enough room for around 16 volumes with full-sized names; more if the names aren’t full-sized.
  4237. System 7 Chooser:
  4238. The System 7.0 Chooser fixes the problem with the NBP buffer completely. It dynamically sizes the NBP LookupName return buffer. So, if numGotten => maxToGet, it will make the return buffer larger and increase the value of maxToGet. The System 7.0 Chooser starts with retBuffSize=1024 and maxToGet=256.
  4239. The AppleShare 7.0 and 3.0 RDEVs increased the size of the afpGetSrvrParms reply buffer to 1728 bytes. That’s still not big enough to get 255 volumes (the AFP limit) with full-sized names. However, it is big enough for 50 volumes with full-sized names, the maximum number of volumes supported by AppleShare 3.0.
  4240. For both System 6 and 7 Choosers, the only limits imposed on the zone are the List Manager limits of 32K of data per list. If each zone name were 33 characters, for example, that would give you space for roughly 1000 zones.
  4241. Server and workstation clock times
  4242. Date Written:  2/25/92
  4243. Last reviewed:  4/22/92
  4244. If I hook up two Macintosh computers over LocalTalk, turn on Personal File Share, mount one computer’s volume on the other, and make changes to files on each machine, the Get Info mod dates are not adjusted. In my case, machine A’s clock said 10:20 and machine B’s said 10:30. From machine B, I made a change to a file on machine A. Then, still on machine B, I did a Get Info on that machine A file. Its mod date said 10:20. I then instantly made a change to a file (from machine B still) on machine B and did a Get Info on it and its mod date was 10:30. In other words, the mod dates were not adjusted and reflected the time of the machine each file was located on. Am I misinterpreting something?
  4245. ___
  4246. The way the workstation computes the server time is not quite as straightforward as is documented in Inside AppleTalk, 2nd edition, page 13-21. When a workstation logs onto a server (File Share or AppleShare), the difference between the workstation’s clock and the server’s clock (s – w) is computed. All subsequent server date/time values as seen by the workstation are computed by adding this difference (s – w) to the server data/time (workstation time = server time + (s – w)).
  4247. However, it looks as if the Macintosh workstation also uses the following algorithm to compute the adjusted server time:
  4248. •    if the offset (s – w) is 15 minutes or less, report the server time as is
  4249. •    if the offset (s – w) is greater than 15 minutes, compute the offset rounded up to the nearest 30 minute interval.
  4250. For example, let’s say you have two machines, A and B. B logs on to A. B then goes and modifies a file on A. Listed below are the clock times that the modification took place, and in the rightmost column is the mod. time that B would see for the modified file on A.
  4251.     A time               B time              mod. time as seen by B
  4252.     ------               ------              ----------------------
  4253.     11:09                11:22                        11:09
  4254.     11:04                11:20                        11:34
  4255.      4:34                 7:14                         7:05
  4256.     11:22                11:53                        11:52
  4257. In the first example, the difference (s – w) is (11:22 – 11:09) = 13 minutes. Since 13 is less than 15 minutes, B sees the server time as is. In the second example, (s – w) is (11:20 – 11:04) = 16 minutes which is greater than 15 minutes so compute the offset to the nearest 30 minute interval (30 – 16) = 14, and 11:20 + 14 = 11:34. In the third example, (s – w) is (7:14 – 4:34) = 2:40 which is greater than 15 minutes so compute the offset to the nearest 30 minute interval (30-40) = –10, and 7:14 – 10 = 7:05. In the last example, (s – w) is (11:53 – 11:22) = 31 minutes so compute the offset to the nearest 30 minute interval 30 – 31 = –1, and 11:53 – 1 = 11:52.
  4258. You are probably asking why the 15-minute cushion and why round to the nearest 30-minute interval? Possibly it’s an attempt to approximate a modification time somewhere in between the workstation and server times.
  4259. PBCatSearch on AppleShare volumes
  4260. Date Written:  3/11/92
  4261. Last reviewed:  5/21/92
  4262. PBCatSearch acts differently on a local hard disk than on an AppleShare volume. Say, after a couple of successful PBCatSearch operations on a volume, the user modifies the directory by duplicating, renaming, or removing a file. An error is returned, and (theoretically), the search can continue. If you do this on a local hard disk, everything is cool. After making the change, the next PBCatSearch call returns -1304 (catChangedErr), but subsequent calls return noErr and continue to find files. However, if you run this on an AppleShare 3.0 volume, the first call after the change returns -5037 (afpCatalogChanged), but all following calls continue to return that error, and “find” the same file that was found on the last good attempt. So what gives?
  4263. ___
  4264. The afpCatSearch AFP call does not map exactly to the File Manager’s PBCatSearch call. This isn’t uncommon in File Manager to AFP translations because AFP calls are designed to be more general so they can be implemented on platforms other than the Macintosh. In some cases, AFP keeps more information than the Macintosh requires (for example, ProDOS file type mapping information for Apple II systems and short names for DOS workstations) and in other cases Macintosh-specific information is “generated” by the Macintosh workstation software (for example, allocation block sizes in the Volume Control Block). Here are specific differences I’ve found between PBCatSearch and afpCatSearch:
  4265. •    afpCatSearch and the AppleShare workstation implementation of PBCatSearch do not use ioSearchTime. The AppleShare 3.0 server searches for up to 1 second or 4 matches maximum and then returns to the workstation with whatever matches (0-4) are found within areas of the disk that user has access to. The AppleShare workstation keeps asking for the number of matches requested minus the total matches returned until it gets the number requested, or the server returns an error.
  4266. •    AFP 2.1 does not support both physical and logical fork lengths. If a PBCatSearch call uses fork lengths, the upper bound (in the afpCatSearch Spec2 field which comes from the ioSearchInfo2 record) becomes the maximum of the logical and physical lengths and the lower bound (in the afpCatSearch Spec1 field, which comes from the ioSearchInfo1 record) becomes the minimum of the logical and physical lengths.
  4267. •    AFP 2.1 does not support the fsSBNegate ioSearchBits bit. If a PBCatSearch call uses fsSBNegate, that bit will be ignored by the AppleShare workstation and server and you’ll get back exactly the opposite of what you expected. This is an unfortunate omission from AFP 2.1. Because it is implemented this way in at least two shipping servers, the fsSBNegate cannot be added without a revision to the AFP specification.
  4268. •    The File Manager PBCatSearch call doesn’t return any matches when a catChangedErr occurs. However, it does return an updated ioCatPosition record which can be used to make another PBCatSearch call (this may result in your search either missing a few entries or getting a few duplicate matches). afpCatSearch does not work that way. afpCatSearch only returns AFP reply data (which includes the ioCatPosition record) if the FPError is noErr or afpEofError. The current ioCatPosition record is not returned to the workstation if any other error occurs. So, if an afpCatalogChanged error occurs, the ioCatPosition record is not returned to the workstation and the workstation returns ioCatPosition to the caller of PBCatSearch unchanged. Since the ioCatPosition record is still invalid, calling PBCatSearch again with the same invalid ioCatPosition record will just return the afpCatalogChanged error again. The conclusion from this explanation is that you can continue a search if PBCatSearch returns a result of noErr or catChangedErr. The search completed if PBCatSearch returns a result of eofErr. All other results from PBCatSearch (including afpCatalogChanged) indicate that you must restart the search from the beginning by clearing the initialize field of the ioCatPosition record.
  4269. AppleShare Prep file and boot-mounting volumes
  4270. Date Written:  8/25/92
  4271. Last reviewed:  9/15/92
  4272. I have selected AppleShare volumes to mount at system startup by checking the volumes in the Chooser list. If I’m on a nonextended network and I call an extended network via AppleTalk Remote Access and log into a remote server via the Chooser and AppleShare, an error alert will say “The AppleShare Prep file needed some minor repairs. Some AppleShare startup information may be lost” and all the information about my local nonextended network will be cleared out of the AppleShare Prep file, so I loose all my log-in IDs and passwords for my local servers. The same thing happens going back the other way (extended to nonextended). Why is this happening?
  4273. ___
  4274. There are several problems you can run into when you connect two networks (and that’s what you’re doing when you use AppleTalk Remote Access when you’re already connected to a network). The problems are usually the result of duplicate names or duplicate node numbers.
  4275. The “boot mount list” (BML) kept in the AppleShare Prep file stores the location of volumes that you want mounted at boot time. Part of that location is the zone name. If you create entries to the BML when you aren’t on an extended network (that is, when you have no zones), the zone name stored in the BML is “*” (“*” is AppleTalk’s shorthand for “this zone”). If you create entries to the BML when you are on an extended network (that is, when you have zones), then the zone name stored in the BML is the zone name of the server.
  4276. The boot mount code checks the validity of the BML when the system starts up, and the Choose checks the validity of the BML when it’s opened. If there are no zones, then entries with zone names other than “*” are cleared out and an alert saying “The AppleShare Prep file needed some minor repairs. Some AppleShare startup information may be lost” is displayed because those entries aren’t valid. If there are zones, then entries with zone names of “*” are cleared out and the alert is displayed because the “*” zone name isn’t a reliable way to save the zone location of a server on an extended network. The “*” zone isn’t reliable for storing the zone name because a workstation can easily be moved from zone to zone, keeping the same NBP object and NBP type names. This is especially true with AppleTalk phase 2, which supports multiple zones on a single network (for example, multiple zones on the same piece of Ethernet cable).
  4277. The workaround for boot-mounting volumes is to create alias files to the file servers you want to mount at boot time and then drop those alias files into the Startup folder inside your System Folder. The only drawback to this is aliases don’t save the user’s password. If you need boot-mounted volumes without the password dialog, you’ll have to use guest access.
  4278. NW 520 - AppleTalk Overview Q&As
  4279. Networking    
  4280. Revised by:    Developer Support Center    September 1993
  4281. Written by:    Developer Support Center    October 1990
  4282. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4283. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4284. New Q&As this month:
  4285. Documentation for creating an AppleTalk-aware network device
  4286. Documentation for creating an AppleTalk-aware network device
  4287. Date Written:  1/12/93
  4288. Last reviewed:  6/14/93
  4289. Where can I find information for creating an AppleTalk-aware network device?
  4290. ___
  4291. The Inside AppleTalk reference provides much of the protocol information required for your device to communicate with networked Macintosh systems. Inside AppleTalk is available from APDA (#C0078LL/B).
  4292. For writing hardware device drivers, the Macintosh AppleTalk Connections Programmer’s Guide discusses information on writing ADEVs and 'atlk' and driver resources. This guide helps one to understand the workings of the Link Access Protocol Manager, and how packets are handled to make sure they go out through the right port.
  4293. Apple doesn’t provide information about the hardware design of an AppleTalk-aware device. In addition, information concerning the hardware layer of LocalTalk hasn’t been made available other than that provided in Inside AppleTalk. The best source of information on this subject probably is from the Internet or some other N&C development community. For Ethernet compatible devices, some of the information that you’ll need can be obtained from the developer notes available from the vendors of Ethernet chips, such as National Semiconductor, Inc., manufacturer of the SONIC chip.
  4294. Another useful tool for developing such a product is a network sniffer, so that you can watch the packet exchange between devices, and compare the exchange with a similar AppleTalk device. This will help in determining whether your device has correctly implemented the protocol. You can probably find product information regarding the various sniffers available by looking on the Redgate icon on AppleLink or in your favorite product catalog.
  4295. Broadcasting to all internet nodes
  4296. Date Written:  9/22/92
  4297. Last reviewed:  6/14/93
  4298. I want to send a Broadcast to all the nodes on an internet, whether EtherTalk or LocalTalk, when my application comes up. I’m not sure which AppleTalk protocol to use. I tried using ALAP and DDP but couldn’t get either to work.
  4299. ___
  4300. Unfortunately, you can’t broadcast to an entire AppleTalk internet. In order to limit network overload, broadcast packets are localized. On AppleTalk, they don’t extend over zones and, on Ethernet, they don’t cross bridges. What you might do, however, is something roughly like the following:
  4301. Server side:
  4302. 1. Initialize your application by creating a socket in the “server” address range:
  4303.    ioParam.ioNamePtr = "\p.MPP";
  4304.    ioParam.ioMisc = (Ptr) 0x80000000;  /* Server flag */
  4305.    PBOpenSync(&ioParam);
  4306. 2. Create an ATP socket:
  4307.    POpenATPSkt(&atpParam, 0); /* Synchronous */
  4308.    gMySocket = atpParam.ATP.atpSocket;
  4309. 3. Register your name. The NBP objStr should be the name of the system your application is running on. You can use GetString(-16413) to get the system name on System 7 (or -16096 to get the Chooser name). The NBP typeString should be a name unique to your application. Note: be sure to remove the name before your application terminates. If you get error -1027 (nbpDuplicate), a previous instance of your application terminated without removing the name. Just call PRemoveName and try again.
  4310. 4. Your server should now post an ATPRead and wait for messages.
  4311. Client side:
  4312. The “client” is the part of your application that looks for servers. The algorithm is, roughly, as follows:
  4313. 1. Use GetZoneList to get a complete list of AppleTalk zones. Make sure you handle the “no zones” case correctly.
  4314. 2. For each zone, use PLookupName to get a list of servers with the NPB typeStr that the “server side” registered.
  4315. 3. For each found entity, use NBPExtract to get the entity name and the addrBlock. The entity name gives you the “human readable” text that identifies the network zone and system name, while the addrBlock lets you send ATP messages to the other system.
  4316. The AppleTalk program interface is described in Inside Macintosh Volumes V and VI. Use these as your primary reference, referring to Inside Macintosh Volume II only when necessary.
  4317. Note that you have to figure on at least 15 seconds per zone. This means that, if you’re trying this algorithm on some huge network (like the Apple engineering network), your application will probably need over a half-hour to probe every zone. The reason for mentioning this is that some applications are using network-uniqueness as a form of user license enforcement. If you do this, it would be unfair to the honest user to stall the application for a half-hour to check for duplicates.
  4318. Another application use would be for systems that maintain a central server, such as for a database, that handles many clients. Here, you probably should ask the user for the zone:node of the server, remember this in your application’s preference file, and look for that server.
  4319. One other thing: In writing this type of program, the SetSelfSend capability is extremely helpful: that way, you can debug both server and client functions on one machine — indeed in one application. Even if you don’t normally use SetSelfSend, make sure your application handles it as it is a global state for all AppleTalk connections on the machine.
  4320. How to get the User and Computer names used by AppleTalk
  4321. Date Written:  11/27/91
  4322. Last reviewed:  6/14/93
  4323. I’d like to use the same names that the system uses to identify itself on the AppleTalk network in my program. Where can I find those names?
  4324. ___
  4325. The names used by the system for network services are stored in two 'STR ' resources in the System file. Your program can retrieve those names with the Resource Manager’s GetString function.
  4326. Only one of the names is available in systems before System 7: the name set by the Chooser desk accessory. That name is stored in 'STR ' resource ID -16096. With System 7, the Sharing Setup control panel lets the user assign two names for network services: the Owner name and the Computer name.
  4327. The Owner name is the name stored in 'STR ' resource ID -16096; it identifies the user of the Macintosh. The Owner name is used by System 7 for two primary purposes: to identify the owner of the system when accessing the system remotely through System 7 file sharing or through the user identity dialog used by the PPC Toolbox (and Apple Event Manager), and to serve as the default user name when logging on to other file servers with the Chooser.
  4328. The Computer name (also known as the Flagship name) is the name stored in 'STR ' resource ID -16413; it identifies the Macintosh. The Computer name is the name used by system network services to identify themselves on the AppleTalk network. For example, if your system’s Computer name is “PizzaBox,” the PPC Toolbox registers the name “PizzaBox:PPCToolBox@*” when you start program linking, and file sharing registers the name “PizzaBox:AFPServer@*” when you start file sharing.
  4329. Which AppleTalk routines can & can’t be called at interrupt time
  4330. Date Written:  6/19/91
  4331. Last reviewed:  6/14/93
  4332. Can any AppleTalk routines be called at interrupt time? Inside Macintosh says that DDPWrite and DDPRead can’t be called from interrupts. If all higher-level AppleTalk protocols are based on DDP, it seems that they all would not work.
  4333. ___
  4334. The AppleTalk routines you can’t call at interrupt time are the original AppleTalk Pascal Interfaces listed in Inside Macintosh Volume II; these are also known as the “Alternate Interface” AppleTalk routines, or ABPasIntf.
  4335. The Alternate Interface routines cannot be called at interrupt time because they allocate the memory structures needed to make the equivalent assembly language AppleTalk call. For example, when the NBPLookup routine is called, it’s passed a handle to an ABusRecord. NBPLookup then has to allocate an MPPParamBlock and move the parameters from the ABusRecord into the newly allocated MPPParamBlock. Then NBPLookup makes a LookupName call, passing it the MPPParamBlock. When LookupName completes, NBPLookup must move results into the ABusRecord and release the memory used by the MPPParamBlock. Since memory is allocated and released within the routine, it cannot be called at interrupt time.
  4336. With that out of the way, the calls you can make at interrupt time (with some restrictions listed below) are what Apple calls the “Preferred Interface” AppleTalk routines. Most of the Preferred Interface routines are listed on page 562 of Inside Macintosh Volume V. There are a few additional calls that were added after the publication of Inside Macintosh Volume V; they’re documented in the AppleTalk chapter of Inside Macintosh Volume VI.
  4337. The Preferred Interface AppleTalk routines can be made at interrupt time as long as:
  4338. • You make them asynchronously with a completion routine (that is, the asynch parameter must be TRUE and you must provide a pointer to the completion routine in the ioCompletion field of the call’s parameter block). Making a call asynchronously and polling ioResult immediately afterward within the same interrupt-time code (which is basically the same as making the call synchronously) is not the same as using a completion routine.
  4339. • They are not listed as routines that may move or purge memory. The Preferred Interface routines do not allocate or dispose of any memory, since they’re just high-level ways to make the assembly language AppleTalk calls and are not built upon the old Alternate Interface routines.
  4340. X-Ref:
  4341. Macintosh Technical Note “Using the High-Level AppleTalk Routines”
  4342. Macintosh Technical Note “AppleTalk Interface Update”
  4343. Macintosh Technical Note “Avoid Use of Network Events”
  4344. AppleTalk and INITs
  4345. Date Written:  9/5/91
  4346. Last reviewed:  6/14/93
  4347. Does AppleTalk work the same with an INIT as with an application? I’m using only Name Binding Protocol (NBP) and Datagram Delivery Protocol (DDP) stuff.
  4348. ___
  4349. Yes! Responder is an example of an INIT that utilizes the NBP to register a Macintosh on the network. NBP requires DDP, so it is also present. AppleTalk is loaded before any INITs, which makes it available to them.
  4350. Install AppleTalk with Installer instead of drag-installing
  4351. Date Written:  12/3/91
  4352. Last reviewed:  6/14/93
  4353. We have problems using AppleTalk version 56 on a Macintosh Plus under System 6. The problems go away when we drop AppleTalk version 52 into the System Folder. What’s going on?
  4354. ___
  4355. AppleTalk version 56 isn’t working for you because you just copied the AppleTalk file into the System Folder of your Macintosh with the Finder (this is known as a “drag-install”). All versions of AppleTalk from version 53 up through the current version must be installed by an Installer script. If you drag-install those versions of AppleTalk, several very important system resources won’t be copied into the System file and AppleTalk won’t work.
  4356. Apple software products that require AppleTalk version 53 or greater always include the Installer and Installer script that copy all system resources needed correctly. Apple also supplies the source to an Installer script that you can use if you license AppleTalk to ship with your products. See the “AppleTalk Licensing Disk 3.2” folder on the latest Developer CD for a look at the Installer script code. As usual, you’ll need to contact Software Licensing at AppleLink address SW.LICENSE if you want to ship AppleTalk with your products.
  4357. Preferred AppleTalk calls and AppleTalk version
  4358. Date Written:  1/8/92
  4359. Last reviewed: 6/14/93
  4360. Do I need AppleTalk version 48 to call AppleTalk routines using the preferred AppleTalk interface?
  4361. ___
  4362. The preferred AppleTalk routines don’t require AppleTalk version 48. You can make any of the AppleTalk calls listed in Inside Macintosh Volume II from a Macintosh Plus. To make .XPP driver calls listed in Inside Macintosh Volume V, you’ll need to use AppleTalk version 48. To make the new AppleTalk calls listed in Inside Macintosh Volume VI (and the Macintosh Technical Note “AppleTalk Phase 2 on the Macintosh”), you’ll need version 53 or later. To make ADSP calls to the .DSP driver, you’ll need to either install ADSP or use AppleTalk version 56 or later which includes the .DSP driver.
  4363. Using AppleTalk self-send mode
  4364. Date Written:  4/20/92
  4365. Last reviewed:  6/14/93
  4366. What’s the recommended method for allowing an AppleTalk node to send packets to itself using AppleTalk’s self-send mode (intranode delivery), assuming customers are running various versions of AppleTalk? There used to be a control panel called SetSelfSend that would turn on AppleTalk self-send mode at startup time. Should we use that control panel or should we use the PSetSelfSend function in our program to set the self-send flag ourselves?
  4367. ___
  4368. AppleTalk self-send mode requires AppleTalk version 48 or greater. You can check the AppleTalk version with Gestalt or SysEnvirons. All Macintosh models except for the Macintosh XL, 128, 512, and Plus have AppleTalk version 48 or greater in ROM.
  4369. The SetSelfSend control panel is still available on the Developer CD Series disc (Tools & Apps:Intriguing Inits/cdevs/DAs:Pete’s hacks-Moof!:SetSelfSend). However, we don’t recommend it as a solution if you need to use self-send mode in your program. Instead, you should use the PSetSelfSend function to turn self-send mode on with your program.
  4370. AppleTalk’s self-send mode presents a problem. Any changes made to the state of self-send will affect all other programs that use AppleTalk. That is, self-send mode is global to the system. Because of this, programs using self-send should follow these guidelines:
  4371. • If you need self-send for only a brief period of time (for example, to perform a PLookupName on your own node), you should turn it on with PSetSelfSend (saving the current setting returned in oldSelfFlag), make the call(s) that require self-send, and restore self-send to its previous state.
  4372. • If you need self-send for an extended period of time (for example, the life of your application) in which your program will give up time to other programs, you should turn self-send on and leave it on — do not restore it to its previous state! Since other programs running on your system (that aren’t well-behaved) may turn off self-send at any time, programs that require self-send should periodically check to make sure it’s still on with either PSetSelfSend or PGetAppleTalkInfo. Apple’s system software has no compatibility problems with self-send — that is, it doesn’t care if it’s on or off — so leaving it on won’t hurt anything.
  4373. Documentation describing AppleTalk 56 and 57 differences
  4374. Date Written:  8/14/92
  4375. Last reviewed:  6/14/93
  4376. What are the differences between AppleTalk 56 and 57 in terms of features, bug fixes, interface, and any technical changes related to driver interfaces?
  4377. ___
  4378. The primary difference between the two versions of AppleTalk involves support for AppleTalk Remote Access, and multinodes. “Multinode” is the capability for a workstation to acquire a node ID separate from that of the workstation user node. AppleTalk Remote Access uses a multinode to provide services for the remote connection via the modem. For more information concerning the differences between the two revisions, there are two documents that you should read. The Macintosh Technical Note “AppleTalk, the Rest of the Story” (formerly #311, “What’s New With AppleTalk Phase 2”) explains many of the changes. You can also read the release notes, located on the Developer CD by this path:
  4379.     Dev.CD Aug 92: Tools & Apps: Networking & Communications: AppleTalk Release Notes: 
  4380.     AppleTalk 56-->57 Changes 
  4381. This document discusses many of the bug fixes implemented in the new release.
  4382. Different AppleTalk versions OK for nodes
  4383. Date Written:  8/14/92
  4384. Last reviewed:  6/14/93
  4385. Is it OK for different nodes to run different versions of AppleTalk on a network?
  4386. ___
  4387. You don’t need to run the same version of AppleTalk for each node on the network. However, AppleTalk versions 53 and greater support AppleTalk Phase 2, so if you’re working on an application that depends on the Phase 2 support (for instance, using the NBP wildcard character “≈”), you’ll need to use AppleTalk version 53 or later for all nodes running that application.
  4388. NW 525 - AppleTalk Remote Access Protocol Q&As
  4389. Networking    
  4390. Revised by:    Developer Support Center    September 1993
  4391. Written by:    Developer Support Center    October 1990
  4392. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4393. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4394. New Q&As for this month:
  4395. PBRemoteAccess “error = -17”
  4396. ARA Developer’s Toolkit documentation fix for variable pb
  4397. PBRemoteAccess error = -17
  4398. Date Written:  11/19/92
  4399. Last reviewed:  6/14/93
  4400. We receive an error = -17 from PBRemoteAccess. Why?
  4401. ___
  4402. What this means is that the Remote Access Manager hasn’t been loaded into memory. Loading the Remote Access Manager into memory takes up valuable RAM space. You should do this only when necessary. Usually, this is done just before calling Connect. You can load the Remote Access Manager into memory yourself using the Load command (see page 7 of the ARA Developer’s Toolkit). However, you should really only call Load just before you call Connect. Calling Load before you make the Status call doesn’t really buy you anything. If you do this (and currently no connection is established) you’ll get the -5833 “PORTDOESNOTEXIST” error. This simply means that the Remote Access Manager is loaded but the user port hasn’t been opened—that is, there’s no connection (ARA 1.0 supports one connection through the user port).
  4403. Keep in mind also that if you do call Load you must eventually balance it out with an Unload call (see page 7 of the ARA Developers Toolkit). Failure to do so could cause problems. Typically, you’d call Load just before you call Connect, and then after you call Disconnect you’d call UnLoad.
  4404. ARA Developer’s Toolkit documentation fix for variable pb
  4405. Date Written:  11/19/92
  4406. Last reviewed:  6/14/93
  4407. In the ARA Developer’s Toolkit manual, at the bottom of page 12, the variable pb is declared as “TRemoteAccessStatusParam.” Shouldn’t this read “TRemoteAccessParamBlock”?
  4408. ___
  4409. Yes, for this specific example pb should be declared as type TRemoteAccessParamBlock. Thanks for pointing out the error.
  4410. AppleTalk Remote Access (ARA) password
  4411. Date Written:  1/6/92
  4412. Last reviewed:  6/14/93
  4413. I often connect to a network via AppleTalk Remote Access (ARA) without mounting an AppleShare server (to print, for example). Do I have to mount an AppleShare volume to change my ARA (network, not server access) password or is there another way? Does changing the password associated with the AppleShare volume I’m mounting affect the ARA network access password?
  4414. ___
  4415. Yes, the only way currently to change your AppleTalk Remote Access (ARA) password is via mounting an AppleShare volume or by changing the password as the AppleShare (or FileShare) administrator on the ARA host. The System 7 File Sharing and AppleShare 3.0 file servers, the PPC toolbox, and ARA all share the Users & Groups file, but typically only the AppleShare client gives a way to change the password.  Remotely changing the AppleTalk Remote Access password can be accomplished by mounting an AppleShare volume on the ARA host, and changing the password for that specific AppleShare volume. This updates your password in the Users & Groups setup, which is the same one used by ARA (hence the doubly changed password). If you were to mount a volume on a Macintosh other than the ARA Macintosh, this would of course be a separate Users & Groups file, and changing this password would not affect your ARA password.
  4416. The Users & Groups libraries in the AppleShare 3.0 Developer’s Kit gives developer applications running on the server machine a way to manipulate the Users & Groups file. It sounds like you’re mostly interested in manipulating your password from a user perspective (rather than writing an application to do it), however, so this may not be all that pertinent to you.
  4417. ARAP and PGetAppleTalkInfo bug workaround
  4418. Date Written:  2/6/92
  4419. Last reviewed:  6/14/93
  4420. After connecting to a remote network via AppleTalk Remote Access (ARA) I can call PGetAppleTalkInfo and it returns the proper zone name. However, after disconnecting, PGetAppleTalkInfo still returns the remote network’s zone name instead of “*” or nothing as I would expect. Is there some period of time I should wait before expecting the zone name and network number to return to zero (no internet)?
  4421. ___
  4422. This is, in fact, a bug with ARA version 1.0. Apple is investigating the problem and there will be a fix in a future release. An easy workaround is to check the GetZoneList or GetMyZone call to see if it returns any zones.
  4423. Calling ARA Connect without using Remote Access file
  4424. Date Written:  4/29/92
  4425. Last reviewed:  6/14/93
  4426. How can I call Connect in AppleTalk Remote Access without an existing ARA connection file created by the Remote Access application?
  4427. ___
  4428. This isn’t directly possible, because without the ARA connection file your program becomes tied to the underlying link tool. The file was implemented so that in the future, when there are different link tools for the different link types, the program will know the link type and tool, plus associated link-specific data to use. To connect without the ARA connection file requires knowledge of the link tool data structures used by each individual link tool. Because these may change, your code may break.
  4429. However, there’s a roundabout way of calling Connect. It requires that you first establish a connection using a document created by the ARA application. Next, make the IsRemote call, setting the optionFlags to ctlir_getConnectInfo (see page 11 of the AppleTalk Remote Access Application Programming Interface Guide). This will cause the information necessary to create the remote connection (connectInfoPtr) to be returned. You would then save this connectInfo data in your application, and when you want to connect sometime later, you would pass this data to the Connect call (in the connectInfo field).
  4430. NW 530 - AppleTalk Transaction Protocol Q&As
  4431. Networking    
  4432. Revised by:    Developer Support Center    September 1993
  4433. Written by:    Developer Support Center    October 1990
  4434. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4435. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4436. New Q&As this month:
  4437. Responder protocol documentation not available
  4438. Date Written:  11/5/90
  4439. Last reviewed:  8/1/92
  4440. Can you please point us to the note that describes the Responder protocol? I recall seeing it documented somewhere.
  4441. ___
  4442. If you have seen any Responder documentation around, it must be bootleg documentation. After talking with the AppleTalk engineers, I was assured that this documentation is not available. Some people wanted it available; others didn’t. Guess who won.
  4443. Anyway, the Responder uses ATP (AppleTalk Transaction Protocol) as well as AEP (AppleTalk Echo Protocol) to send/receive data from one machine to another. If you have a copy of Peek and Inter•Poll you can check this out on the network to better understand it. It’s a pretty straightforward implementation. AEP and ATP are documented in Inside AppleTalk. These, coupled with Gestalt or SysEnvirons, to get any machine-specific information you may wish to send, should be all you need to understand how the Responder works.
  4444. NW 535 - Datagram Delivery Protocol Q&As
  4445. Networking    
  4446. Revised by:    Developer Support Center    September 1993
  4447. Written by:    Developer Support Center    October 1990
  4448. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4449. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4450. Datagram Delivery Protocol (DDP) header checksum field
  4451. Date Written:  4/2/91
  4452. Last reviewed:  6/14/93
  4453. Does the Macintosh client pay attention to and validate Datagram Delivery Protocol (DDP) checksums within long DDP packets received?
  4454. ___
  4455. DDP is a client of the AppleTalk Transaction Protocol (ATP), which is a client of the AppleTalk Session Protocol (ASP) and AppleTalk Filing Protocol (AFP). DDP is told by the entity for whom it is a client whether it should use checksumming. For performance reasons, our version of ATP does not specify that DDP use the checksum. Both AppleShare and the AppleShare client are out of the loop; neither can specify whether or not to use the DDP checksum. 
  4456. The LAP layer performs checksumming, ensuring no on-the-wire corruption. The only benefit of DDP checksumming is end-to-end corruption detection when the packet has travelled over a malicious router that has validly received a DDP packet on one net, changed the packet, re-computed the LAP checksum, and sent it out on another cable. Because of the performance hit of DDP checksumming and the rarity of such a malicious router, it was decided not to request DDP checksumming.
  4457. ZIP Query packet zero checksum value
  4458. Date Written:  3/3/92
  4459. Last reviewed:  6/14/93
  4460. Is a zero checksum value indicative of no checksum provided with the Zone Information Protocol (ZIP) packet?
  4461. ___
  4462. True, a zero checksum in any DDP packet with an extended header (including ZIP packets) indicates that a checksum was not performed. See Inside AppleTalk, 2nd Ed. pages 4-17.
  4463. How to write a DDP read with completion routine
  4464. Date Written:  2/28/92
  4465. Last reviewed:  2/28/92
  4466. The PWriteDDP call is nothing like a PReadDDP call. We want to do an AppleTalk Datagram Delivery Protocol (DDP) read with a completion routine (to wait for an echo reply), but with only the old style call, this is impossible. Is a completion routine for DDPRead possible?
  4467. ___
  4468. Because of the ABRecord structure handling implemented in the DDPRead call, an asynchronous version of this call was not possible.  DDPRead implements Memory Manager calls. As a result, no preferred style of call was implemented for DDPRead. The alternative is to alter your process to use the POpenSkt call instead. As part of the POpenSkt function, you'll need to define a socket listener.  A sample socket listener can be found in the Tech Note "AppleTalk Timers Explained" (it’s written in MPW assembly code). In addition, a sample program called DMZ, on the System 7 Golden Master CD, uses that echo socket listener code fragment.
  4469. Communication between players in a game on an AT network
  4470. Date Written:  12/18/90
  4471. Last reviewed:  2/1/91
  4472. How can I use the broadcast mode in an AppleTalk DataGram Delivery Protocol (DDP) layer to communicate with the other players of a game that is on a network and not interfere with other network users?
  4473. ___
  4474. The broadcast mode may seem like a solution, but Apple doesn’t recommend using broadcast mode. Applications like games generally end up sending LOTS of update packets to other players of the games. If your program broadcasts those packets, then all nodes on your network will be interrupted for every packet sent and that can cause performance problems on every machine on a network. In Apple supplied software, broadcast mode is only used when packets need to be sent to every node on a network. For example, Name Binding Protocol (NBP) Lookup packets are broadcast because the network address is unknown.
  4475. The following suggestions should help implement communications between players.
  4476. The DDP protocol layer does not guarantee delivery of packets (the disadvantage), but has very little overhead (the advantage). If you require delivery of all packets and can take a small additional performance hit, you should use the AppleTalk Transaction Protocol (ATP) layer.
  4477. The DDP type you use must be in the range of $10-$FF. The DDP type you choose to use (in that range) probably won’t make a lot of difference unless you define multiple clients to DDP within your socket listener. Packets addressed to your socket will get sent to your socket listener. How you use the type is up to you (as long as you stay out of the reserved range).
  4478. You should open a dynamic socket (i.e., use 0 for the socket number and use the socket number in the range $80-$FE that is returned) with the OpenSocket call and then register a name on the network for that socket with the RegisterName call. If all copies of the game register with the same NBP type, then you can use the LookupName call to find other players on the network. Once you’ve found other players and decided who you’re going to play against, you just address each DDP packet to the internet address(es) of the other player(s) socket(s). Several multi-player network games I’ve seen on the Macintosh do just that. (Hint: If you limit games to players on a single network, DDP will use short header packets which are slightly faster to send (8 bytes less per packet).)
  4479. If you build a table (array) of network addresses from those playing a game, you can use this algorithm to send a packet to each player.
  4480. BEGIN
  4481.   { put data into buffer for DDP and set the common parameter block fields: }
  4482.   { Async Flag, Command, Checksum Flag, Source Socket, DDP Type, BDS Pointer }
  4483.   { and Destination Network (if limiting play to a single network). }
  4484.   buildPacket;
  4485.   FOR Player := 1 to NumberOfPlayers DO
  4486.     BEGIN
  4487.       { Set the Destination Node and Destination Socket fields of the }
  4488.       { parameter block to the network address of a player.  That address }
  4489.       { would be in an array of network addresses (one for each player). }
  4490.       setAddress(Player);
  4491.       { Send the datagram to a player using SendDatagram call. }
  4492.       doSendDatagram;
  4493.     END;
  4494. END;
  4495. NW 540 - AppleTalk Ethernet Driver Q&As
  4496. Networking    
  4497. Revised by:    Developer Support Center    September 1993
  4498. Written by:    Developer Support Center    October 1990
  4499. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4500. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4501. “Undefined entry” link errors when opening Ethernet Driver
  4502. Date Written:  8/8/91
  4503. Last reviewed:  6/14/93
  4504. When I try to open the EtherNet driver as described in Inside Macintosh Volume VI on pages 32-80 and 32-81, I get the following undefined entry error messages:
  4505.     ### Link: Error: Undefined entry, name: (Error 28) "DisplaySInfo"
  4506.       Referenced from: Init_Enet in file: Mac_Raid.c.o
  4507.     ### Link: Error: Undefined entry, name: (Error 28) "SaveSInfo"
  4508.       Referenced from: Init_Enet in file: Mac_Raid.c.o
  4509.     ### Link: Error: Undefined entry, name: (Error 28) "SGetTypeSRsrc"
  4510.       Referenced from: Init_Enet in file: Mac_Raid.c.o
  4511. Any clue as to where these are?
  4512. ___
  4513. The “DisplaySInfo” and “SaveSInfo” are bogus procs that the sample writer 
  4514. didn’t take out or comment out.
  4515. However, SGetTypeSRsrc is a legal Slot Manager trap, IF you are using the new 
  4516. version of the Slot Manager. The definitions from the latest interfaces 
  4517. (slots.p, slots.h) are as follows:
  4518.     FUNCTION SGetTypeSRsrc(spBlkPtr: SpBlockPtr): OSErr;
  4519.         INLINE $205F,$700C,$A06E,$3E80;
  4520.     #pragma parameter __D0 SGetTypeSRsrc(__A0)
  4521.     pascal OSErr SGetTypeSRsrc(SpBlockPtr spBlkPtr)
  4522.         = {0x700C,0xA06E};
  4523. The Slot Manager is dispatched via D0 selectors; there is no glue.
  4524. IEEE assigns Ethernet card addresses
  4525. Date Written:  9/16/91
  4526. Last reviewed:  6/14/93
  4527. We need a range of Ethernet card addresses to uniquely identify each Ethernet card we manufacture. We received board IDs and equates from Apple, but not the range of Ethernet addresses.
  4528. ___
  4529. You weren’t sent a range of Ethernet addresses because Apple does not assign them. IEEE is the governing body that you have to contact to get a range of numbers; Apple had to do the same thing to get the numbers for its boards. IEEE will assign you a block of numbers that includes a unique manufacturer’s ID allowing network sniffers to recognize your products.
  4530. Apple Ethernet Cable System power requirements
  4531. Date Written:  9/17/91
  4532. Last reviewed:  6/14/93
  4533. Sections 3.1.2 and 3.1.3 of the “Apple Ethernet Cable System Product Family Overview and Interface Descriptions”  state that pin 1 provides either 12 V/2.1W or 5 V/1.9 W, and that 5 volts will be made available on pins 7 and 8, if the host can supply greater than or equal to 1.9W @ 5 V. Which models do not have 5 V available on pins 7 and 8, which models have 12 V on pin 1, and which have 5 V on pin 1?
  4534. ___
  4535. All known hosts will provide 5 V at pins 7 and 8. It is absolutely NOT recommended that a Multiple Access Unit (MAU) designer use Voltage Agile (pins 1 and 14) powering to power a 5 V-only MAU. It is anticipated that all friendlynet-compliant hosts will supply +5 V to pins 7 and 8. Third parties desiring a 5 V-only MAU should use these pins. 
  4536. MAUs using pins 1 and 14 MUST have a DC-DC converter.
  4537. Apple doesn’t presently have a product that uses +12 V on pins 1 and 14 but may in the future. As this is an “open standard,” at least one clone maker and several third-party Apple printer and card manufacturers use this interface, and others are expected.
  4538. EtherTalk DriverClose function
  4539. Date Written:  11/27/91
  4540. Last reviewed:  11/27/91
  4541. My EtherTalk DriverClose function is never called by the system, so my VBL and interrupt service routines remain active, even though another network device is active. Any ideas or tips on what might be going on?
  4542. ___
  4543. Your findings are as per design. Just because the user decides not to use EtherTalk doesn’t mean that the user no longer wants Ethernet services. For example, the user might be using MacTCP. MacTCP accesses the .ENET driver directly, bypassing the LAP Manager. Should the NetWork cdev close the .ENET driver when the user switches to LocalTalk or TokenTalk while MacTCP is still using the driver, a system crash would likely result.
  4544. Ethernet and Quadra systems
  4545. Date Written:  12/6/91
  4546. Last reviewed:  6/14/93
  4547. The Ethernet connection on our new Quadra system is different from the connection on our Macintosh II Ethernet card. Apparently we need to purchase “Apple Ethernet Media Adapters.” We may reconfigure our existing thin-wire Ethernet network. Do you know of any publications describing the latest technology in setting up an Ethernet network? What are the pros and cons of thin coax, thick coax, twisted pair, or other cables? Does Apple manufacture Ethernet Media Adapters? Is there a cable available that plugs directly into the Quadra’s Ethernet port? Does System 7 File Sharing software execute over an Ethernet network? Under System 7, is it still necessary to activate AppleTalk in order to run EtherTalk?
  4548. ___
  4549. Addison-Wesley has just published a book titled, “Planning and Managing AppleTalk Networks” (ISBN #0-201-52345-0). Networking periodicals such as NetWorld are other good resources for learning about current technology and network cabling system vendors. You might also contact N&C vendors directly for specific information.
  4550. Twisted pair is cheaper and easier to implement than the other media; however, the supported distance is not nearly as great as for thin and thick-wire media. For backbone connections, Fiberoptic Data Distribution Interface (FDDI), while expensive, handles the highest bandwidth.
  4551. Apple manufactures the Apple Ethernet Thin Coax Tranceiver (M0329LL/A), as well as a Tranceiver for UTP (Unshielded Twisted Pair) and an Adapter for Ethernet AUI (Attachment Unit Interface), for adapting to third-party fiber and thick coax transceivers. Each of these transceiver/adapter units has a cable that plugs into the 14-pin connector on the back of the Quadra, the LC Ethernet card, and the new Ethernet NB card (completely different from the older EtherTalk NB card).
  4552. System 7 File Sharing works independently of the hardware connection, so it definitely executes over an Ethernet network. Under System 7 AppleTalk still is required for EtherTalk, although it is possible to bypass AppleTalk. For example, MacTCP, running with the NCSA Telnet Software Package, accesses the Ethernet driver software directly.
  4553. Selecting alternate AppleTalk driver at system startup
  4554. Date Written:  5/3/89
  4555. Last reviewed:  6/14/93
  4556. I need to know how to set the Macintosh parameter RAM field that controls which alternate AppleTalk driver is used at system startup (for example, EtherTalk).
  4557. ___
  4558. We discourage directly setting the parameter RAM. The Network 'cdev' and the 'adev' device work together to handle this. Each type of AppleTalk connection (other than LocalTalk) must have its own 'adev' file. The construction of the 'adev' file is similar to that of a 'cdev' file. For each type of AppleTalk connection, such as EtherTalk, the 'adev' file must contain the following
  4559. resources:
  4560.     'ICN#'
  4561.     'STR '
  4562.     'BNDL'
  4563.     'FREF'
  4564.     owner resource
  4565.     'adev' code resource
  4566.     'atlk' code resource
  4567. The 'adev' and 'atlk' resources are pieces of stand-alone code that reside in the adev file. The 'adev' resource is responsible for handling all control panel interactions with the Network 'cdev'. The 'atlk' resource contains the actual implementation code for the supported AppleTalk connection. When the user selects an AppleTalk connection from the Network control panel, the Network 'cdev ' updates parameter RAM with a value that represents the AppleTalk connection that is currently selected. This value remains in parameter RAM after the user turns off the Macintosh.
  4568. More information about this can be obtained from EtherTalk and Alternate AppleTalk Connections Reference, available from APDA.
  4569. NW 545 - Link Access Protocol Q&As
  4570. Networking    
  4571. Revised by:    Developer Support Center    September 1993
  4572. Written by:    Developer Support Center    October 1990
  4573. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4574. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4575. New Q&As this month:
  4576. AppleTalk and VBL task using self-send mode
  4577. AppleTalk and VBL task using self-send mode
  4578. Date Written:  5/18/92
  4579. Last reviewed:  6/14/93
  4580. To make all AppleTalk calls asynchronously, I have to split the VBL task in pieces:
  4581.     - Setselfsend
  4582.     - check its async finish
  4583.     - StartLookup
  4584.     - check its async finish
  4585.     - Restoreselfsend
  4586.     - check its async finish
  4587. This means that while the selfsend is set to true, other software will be confused when they do a lookup. Also, when the Macintosh is doing I/O on the network, the VBL will set and restore the selfsend flag. Will other AppleTalk calls fail if the SelfSend flag Is set to true, or does selfsend only work on PLookupName?
  4588. ___
  4589. Your method of splitting up the steps of a lookup to yourself during a VBL task using self-send mode is correct, except you needn’t bother restoring the state of self-send since you are giving up time to other processes between calls to your VBL task.
  4590. Self-send mode is a global setting and may affect any AppleTalk calls. When the LAP manager is preparing to send a packet, it checks the destination node. If the destination node is its own node address or the broadcast address, then it sends the packet to itself before putting the packet out on the wire. This usually only affects NBP lookup packets because they are sent to the broadcast address. Most other AppleTalk protocols do not broadcast.
  4591. Programs using self-send should follow these guidelines:
  4592. •    If self-send is only needed for a brief period of time, then you should turn self-send on with PSetSelfSend (saving the current setting returned in oldSelfFlag), make the call(s) that require self-send, and then restore self-send to its previous state.
  4593. •    If self-send is needed for an extended period of time (for example, for the life of your application) where your program will give up time to other programs, then you should turn self-send on and leave it on (don’t restore it to its previous state). Since other programs running on your system (that aren’t well behaved) may turn off self-send at any time, programs that require self-send mode should periodically call PSetSelfSend to make sure self-send stays on. Apple’s system software has no compatibility problems with self-send—that is, it doesn’t care if it’s on or off—so leaving it on won’t hurt anything.
  4594. How to tell if LAP Manager is present
  4595. Date Written:  12/12/91
  4596. Last reviewed:  2/3/92
  4597. What’s the recommended technique for telling whether the user has turned off AppleTalk?
  4598. ___
  4599. The best way to determine whether AppleTalk has been turned off is to use the AppleTalk Transition Queue to alert you to .MPP closures. (This is one of the reasons why the AppleTalk Transition Queue was implemented.) The AppleTalk Transition Queue is available only in AppleTalk version 53 or later, and is documented in the AppleTalk chapter of Inside Macintosh Volume VI, starting on page 32-17. There’s also a code snippet, Transition Queue, in the Snippets folder on the Developer CD Series disc.
  4600. AppleTalk AOpen and AClose codes 7 & 8
  4601. Date Written:  11/1/91
  4602. Last reviewed:  11/27/91
  4603. What are AppleTalk messages 7 and 8? They’re documented in lapequ.a as:
  4604.     AOpen      EQU         7       ; Open an ATlk
  4605.     AClose     EQU         8       ; Close an ATlk
  4606. but what should the adev do with them and what parameters are passed?
  4607. ___
  4608. The AOpen and AClose messages are sent when the .MPP driver is opened and closed, respectively. When the AppleTalk driver is closed, a shutdown message is not sent. Instead, the LAP Manager determines whether an adev is version 3 or greater and, if true, assumes that the adev can respond to the AClose message and sends the message. Conversely, when the .MPP driver is re-opened while the adev is active, the AOpen message is sent to the adev (assuming that the adev is version 3 or greater).
  4609. An important note on this matter is that if you modify your adev to version 3, additional selectors must be supported. These new selectors will be documented in a forthcoming Tech Note.
  4610. NW 550 - MacTCP Q&As
  4611. Networking    
  4612. Revised by:    Developer Support Center    September 1993
  4613. Written by:    Developer Support Center    October 1990
  4614. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4615. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4616. New Q&As in this Technical Note:
  4617. OK to abort a MacTCP name resolver call
  4618. OK to abort a MacTCP name resolver call
  4619. Date Written:   3/9/93
  4620. Last reviewed: 6/24/93
  4621. Is it possible to abort an outstanding MacTCP name resolver call before it completes? The CloseResolver call description says that “[b]efore the application exits, the CloseResolver call must be made to release memory structures and terminate all outstanding domain name server calls.” The very next sentence says that “CloseResolver must not be called until all outstanding resolver calls have been completed.” Which of these statements is correct? If it’s the latter one, then does that mean that if I make a StrToAddr call and it returns cache fault I have to wait for the result proc to be called before my application can quit? How long is that likely to be?
  4622. ___
  4623. According to the MacTCP name resolver code, CloseResolver will abort any currently executing name lookup. In other words, you don’t have to wait until your name resolver completion procedure gets called if you want abort the call.
  4624. Other things to be aware of are that you can’t perform multiple name resolver lookups simultaneously, you can't call the name resolver from interrupt time, and the timeout for name resolver calls is hard-coded to 37 seconds before they’ll complete with an error if no response is received.  All of this information is valid as of MacTCP version 2.0.2 and prior releases as well.
  4625. Maintaining a listening server socket on the Macintosh
  4626. Date Written:  2/1/93
  4627. Last reviewed:  6/14/93
  4628. On the Macintosh, I need to consistently listen on the same port for incoming connections. This behavior is analogous to the Listen and Accept functionality provided by the industry standard socket interface for TCP on UNIX systems. That is, I listen on a port/socket for incoming connections; when a remote system attempts to connect, a new socket is created representing that connection; and the port/socket performing the listen continues to listen for other connection requests.
  4629. When using the TCPPassiveOpen operation under MacTCP, the listen operation doesn’t persist once an incoming connection is established. That is, the stream used to listen for an incoming request becomes the connection with the remote system. Once that connection is established, there’s no stream listening for subsequent connection requests. Is there any way I can keep a listener active at all times? My application needs to have a listener constantly, or at least with as short a window of unavailability as possible.
  4630. ___
  4631. You’re right that with MacTCP’s nonsocket interface there’s no way to maintain a persistent listener using MacTCP. To emulate this functionality, you’ll have to keep more than one listener active at all times. You can do this by queuing multiple TCPPassiveOpen commands asynchronously to the MacTCP driver. How many to queue depends on how fast you expect connections to come in and how quickly you can requeue new opens after connections are made. Three should probably be enough if you expect a relatively small number of connections and you can requeue new parameter blocks as you receive connections.
  4632. PBControl is safe to call at interrupt time in this case. Inside Macintosh X-Ref lists it as unsafe because it’s impossible for them to know what kind of driver you might be calling. For a particular driver, calling it at interrupt time might be totally unsafe, totally safe, or safe to do asynchronously only. In the case of MacTCP, it falls under the “safe if asynchronous” category. Any asynchronous calls to it will queue up and wait, so it’s safe to post them from an interrupt or an ASR. However, since there isn’t an ASR event for Notify, I agree that using an ASR isn’t a solution for you in this case.
  4633. There is some sample code you might find useful. On the Developer CD, under the path “:Technical Documentation:Sample Code:Snippets:Networking:TCP Server:” you’ll find a sample server that uses TCP.
  4634. MacTCP over ARA requires IP Encapsulation service
  4635. Date Written:  12/10/92
  4636. Last reviewed:  6/14/93
  4637. When I dial into my AppleTalk network none of my MacTCP-based software works. I have MacTCP configured with an IP number on the remote machine, and Telnet (a MacTCP-based application) runs fine, but I can’t connect to any of the hosts on the network I’m dialed into. What could be causing this problem?
  4638. ___
  4639. The problem may be because you don’t have a device on the dial-in net to act as a proxy IP Encapsulation service. When you select the AppleTalk icon (such as LocalTalk, EtherTalk, or Dial-In) in the MacTCP control panel, you’re using a MDEV (IP Link layer) that encapsulates the IP data into an AppleTalk packet and sends it out. You therefore need to have something on the other side that will break out the IP data from the AppleTalk packet and send it out as an IP frame on the network you’re dialed into.
  4640. There are several third-party solutions to this problem, the Shiva FastPath and Cayman Gator Boxes being the most common. The feature is normally called IP Encapsulation or KIP. If you use MacTCP this way, you must select the zone via the pop-up menu in the MacTCP control panel that the IP Encapsulation device is in. You must also configure the IP Encapsulation device to give out IP numbers, and set the remote Macintosh to “Server” IP addressing in the MacTCP control panel.
  4641. Note: Two Macintosh systems using IP Encapsulation should be able to communicate peer to peer, but they won’t be able to contact non–IP Encapsulation devices.
  4642. Definition: IP Encapsulation: The act of taking IP data frames (packets) and placing them inside an AppleTalk packet for transport over an AppleTalk-only media (also known as LocalTalk and ARA). Also known as KIP or KSTAR, which are both names left over from the Kinetics FastPath.
  4643. MacTCP ARP limits are hard-coded
  4644. Date Written:  9/22/92
  4645. Last reviewed:  6/14/93
  4646. Is it possible to increase ARP cache size? It appears that MacTCP has memory to cache 35 to 40 entries. If my application sends out IP requests periodically to about 40 unique IP stations, MacTCP drops some entries, and makes an ARP request. Is there any way to program the cache size to a higher limit?
  4647. ___
  4648. Unfortunately, the number of ARP table entries is hard-coded to 20 in the MacTCP source code, and the ARP time-out for aging entries out of the ARP cache is also hard-coded to 10 minutes. There’s no way to change these values, since they are in the code as #defines and used throughout.
  4649. How to cancel transactions under MacTCP
  4650. Date Written:  12/7/90
  4651. Last reviewed:  8/1/92
  4652. How do I cancel transactions (specifically connect requests) under MacTCP? I know that I can specify a timeout; however, I would like the user to be able to hit ‘Command-.’ if the transaction’s tired of waiting. I tried KillIO but that seems to crash.
  4653. ___
  4654. Since MacTCP uses the Control call instead of reads and writes, the killio call is not supported to abort a transaction. You should use Abort and Release. Abort terminates the connection and Release releases the stream. As an alternative, a TCPPassiveOpen could be cancelled by issuing an active open from the same machine on the listening port.
  4655. Porting a TCP/IP application to the Macintosh
  4656. Date Written:  3/19/91
  4657. Last reviewed:  8/1/92
  4658. We need the following to port our mainframe front-end application to the Macintosh:
  4659.   • a C++ compiler compatible with AT&T 2.0 (and ANSI C)
  4660.   • a TCP/IP library with an Application Programming Interface (API) similar to sockets
  4661.   • an Ethernet card
  4662. ___
  4663. MPW C++ is based on AT&T CFront 2.0. For information about CFront 2.0, please refer to the UNIX System V AT&T C++ Language System Release 2.0 Product Reference Manual.
  4664. Sockets is the general UNIX (Berkeley) API for TCP/IP programming. Apple currently offers some libraries that allow you to work with MacTCP but not APIs similar to sockets. Third-party socket libraries for MacTCP are available, however. Also, universities such as the University of Toronto provide public domain socket wrappers for MacTCP.
  4665. Ethernet cards are available from a number of sources, including Apple’s Ethernet cards.
  4666. MacTCP gateway address and subnet mask fields
  4667. Date Written:  5/7/91
  4668. Last reviewed:  6/14/93
  4669. What are the MacTCP Subnet Mask and Gateway Address fields used for?
  4670. ___
  4671. In the TCP/IP protocol, there are a couple of provisions for simplifying the addressing scheme for smaller local networks. One of these is the subnet mask. It allows the sender to identify the destination machine by a shorter address, which is long enough to distinguish all the machines on the local network. This mask is made up of four octets, and is used as a bitwise mask to show how many bits are being used to specify the network number, subnet number, and node. The gateway address field specifies the IP address of the local network’s router. Packets destined for another network are sent to this router, which then transmits the packets to other networks.
  4672. Communicating different processes on the same Mac with MacTCP
  4673. Date Written:  6/5/91
  4674. Last reviewed:  8/1/92
  4675. Is it possible to have both the source and the destination application on the same machine if they are using MacTCP to communicate? If so, what should I do to make sure both applications share the processor so this works properly?
  4676. ___
  4677. It is possible to use MacTCP to communicate to different processes on the same Macintosh computer. Unlike PPC, MacTCP does not bypass the network for same-machine connections, so there is still some “network traffic” involved.
  4678. As far as “sharing” the processor goes, this is very important in what you are doing. Here’s a brief outline of what you need to do:
  4679. • Make asynchronous MacTCP driver calls;
  4680. • If you want to use polled I/O, you can wait for ioResult < 1 to tell when the call completes. Otherwise, you may want to have a completion routine which queues completed calls for processing at event time; or
  4681. • Call WaitNextEvent or EventAvail while waiting for driver calls to complete (this gives time to the other MacTCP applications).
  4682. For a good reference on using “idle procs” to give time to background applications when using MacTCP, refer to the article, “MacTCP Cookbook” in develop, Issue 6 and get the “NewsWatcher” source code from the Developer CD Series.
  4683. How to tell how many of StrToAddr’s network addresses are valid
  4684. Date Written:  8/30/91
  4685. Last reviewed:  6/14/93
  4686. Using StrToAddr, you can receive up to four IP network addresses returned by the service for the host requested, but the MacTCP Programmer’s Guide does not say how to tell how many of the addresses are valid. According to the name resolver code, MacTCP zeros out 4 long words before the StrToAddr lookup and then fills in the addresses it finds. This means that the array contains at most 4 addresses, and is terminated by a zero address (0.0.0.0) if fewer than four addresses are returned.
  4687. MacTCP resolver code is in domain name resolver
  4688. Date Written:  9/17/91
  4689. Last reviewed:  6/14/93
  4690. Is the MacTCP resolver code contained in the domain name resolver (DNR)?
  4691. ___
  4692. The resolver code is contained in the MacTCP DNR, as well as in the MacTCP control panel. The DNR code is stored as a resource file in the System folder and is read into memory as necessary in order to convert host names into addresses. It is used in conjunction with a domain name server or with the local hosts file.
  4693. MacTCP Hosts file location and function
  4694. Date Written:  9/17/91
  4695. Last reviewed:  6/14/93
  4696. Where should the MacTCP Hosts file be located, and who looks for that file?
  4697. ___
  4698. According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), the Hosts file should be located in the user’s System Folder. The file maps machine names to internet addresses, providing the same service as the domain name server. The Hosts file can be used if you have no domain server on your network. It is also suggested that this file be used for frequently used name-to-address mappings. Instructions on setting up the file are included in the MacTCP documentation.
  4699. MacTCP “obtain address” options
  4700. Date Written:  9/24/91
  4701. Last reviewed:  6/14/93
  4702. Under MacTCP, what is the significance of the “obtain address” options, with
  4703. respect to (1) manually, (2) server, and (3) dynamically?
  4704. ___
  4705. According to the MacTCP 1.0 Documentation Kit (APDA #M0217LL/A), “obtain address” means the following:
  4706. • Manually: You will need to fill in some or all of the fields in the IP Address box; 
  4707. • Server: The Internet Protocol (IP) address for the user Macintosh is automatically obtained from a server every time the user Macintosh boots up. This option requires 
  4708.   - a Reverse Address Resolution Protocol (RARP) or Bootstrap Protocol (BootP) server on an Ethernet, or 
  4709.   - a Datagram Delivery Protocol–to–Internet Protocol (DDP-IP) gateway on an AppleTalk network that’s compatible with the Kinetics Internet Protocol (KIP) developed at Stanford (also called “IPTalk”), such as the Shiva Fastpath or Cayman Gatorbox
  4710. • Dynamically: The node portion of the IP address for the user Macintosh is set dynamically every time the user Macintosh boots up. With this option you still need to set some of the fields in the IP Address Box. All these processes are described in further detail in the MacTCP documentation.
  4711. MacTCP and SLIP
  4712. Date Written:  11/6/91
  4713. Last reviewed:  6/14/93
  4714. Does MacTCP actually support SLIP? If not, does Apple plan to provide SLIP support in the future. Does anyone know of any company that does a SLIP for the Macintosh?
  4715. ___
  4716. SLIP is an asynchronous, serial line protocol developed for running TCP/IP over serial communications lines in a point-to-point configuration. SLIP was developed to transmit IP packets over low-speed, sometimes noisy, asynchronous communications lines where error recovery and an efficient line protocol are needed. The SLIP protocol is now being replaced with a new serial line protocol named “PPP,” which uses a more efficient means of establishing a point-to-point IP connection.
  4717. MacTCP includes hooks that let you write different link-layer modules. This makes possible the development of interfaces to SLIP, PPP, and to any other link layer that someone may need, like broadband, X.25, and FDDI. Apple does not currently provide support in MacTCP for SLIP or any other serial line protocol. There are, however, several third-party SLIP extensions available for use with MacTCP.
  4718. MacTCP StrToAddr and header’s hostInfo record structure
  4719. Date Written:  12/12/91
  4720. Last reviewed:  6/14/93
  4721. I'm using MacTCP v1.1 with Think C, and when calling StrToAddr with hostname = "90.25.3.240", the returned addr field has the following:
  4722.     addr [0] = 0X00005A19
  4723.     addr [1] = 0X03F00000
  4724. The correct answer should be addr [0] = 0X5A1903F0. What’s the problem?
  4725. ___
  4726. The StrToAddr problem you are experiencing is related to a shortcoming in the header files. The structure for the hostInfo record you are accessing (from AddressXlation.h)is as follows:
  4727.     typedef struct hostInfo {
  4728.         int rtnCode;
  4729.         char cname[255];
  4730.         unsigned long addr[NUM_ALT_ADDRS];
  4731.     };
  4732. The problem with the way the structure is defined is that rtnCode is defined as an “int.” The size of an int is dependent on your development environment. In MPW, ints are 4 bytes, while Think C uses 2 byte ints as its default. If you’re using Think C, you will see the addresses shifted forward in the storage by 2 bytes, since the rtnCode structure causes the rest of the struct to be shifted forward in memory.
  4733. If you’re using Think C 5.0 or later, you can either check the “Use 4 byte ints” check-box in the preferences, or you can change the header files to use “long” in place of “int” (a Think C long is the same size as an MPW int). A set of header diffs for Think C compatibility with MacTCP is on the latest Apple Developer CD Series disc in Tools & Apps: Networking & Communication: MacTCP 1.1 DTS Header Changes.
  4734. MacTCP EnumCache data enumeration sequence
  4735. Date Written:  12/12/91
  4736. Last reviewed: 6/14/93
  4737. Does MacTCP's EnumCache name resolver call return the data in a particular order or randomly? 
  4738. ___
  4739. Since the EnumCache documentation doesn’t specify any particular sequence for name resolver cache enumeration, it’s best to play it safe and not assume any particular order for the data returned by the call.  Since the internals of the name resolver may change in the future, you probably don’t want to rely on any undocumented data ordering assumptions. If you want the entries separated, the best way probably would be to have a dynamically-sized array for each of the entry types (such as addresses, HInfo, and name servers) and fill them in the EnumCache callback.
  4740. MacTCP addressing modes and Shiva Fastpath
  4741. Date Written:  1/6/92
  4742. Last reviewed:  6/14/93
  4743. When I attempt to connect to a LocalTalk net using MacTCP 1.1, after opening the MacTCP driver, this error occurs: “Error opening driver / Error in getting address (-23004)”. I’m running System 7.0 on a Macintosh IIci with Shiva Fastpath 4.0, and I’ve configured TCP Admin as follows:
  4744.     Indicate Resident Zone
  4745.         Click More
  4746.     Dynamic addressing
  4747.     Range 1 to 65534
  4748.     Enter Gateway Address (address of Fastpath for resident zone)
  4749.     Enter Domain Name & Address
  4750. ___
  4751. The Fastpath won’t work with MacTCP configured to use dynamic addressing. You need to set MacTCP to use server-based addressing. If you change this setting, and the FastPath is configured correctly, you should be up and running.
  4752. MacTCP 1.1 and sending urgent data per RFC 1122 or 793
  4753. Date Written:  4/7/92
  4754. Last reviewed:  6/14/93
  4755. MacTCP 1.1 packets containing “urgent data” have the so-called “urgent pointer” set according to RFC 1122. All our TCP/IP hosts expect a behavior corresponding to RFC 793, however. Is there a possibility to configure MacTCP to this effect?
  4756. ___
  4757. MacTCP can send urgent data according to either RFC 1122 or RFC 793; however, it is not a setting in the driver that determines this. When a programmer makes the TCPSend call, he sets a flag in his parameter block that indicates whether or not to use urgent data, and which version of urgent data to use. Therefore, you would have to modify the program that you are using to set up the parameter blocks appropriately.
  4758. To send urgent data using the non-compliant RFC 793 method, set the urgent flag in the TCPSend parameter block to 2. Any other nonzero value in the urgent flag indicates the RFC 1122 method should be used.
  4759. MacTCP 1.1 ICMP echo request documentation bug
  4760. Date Written:  2/13/92
  4761. Last reviewed:  6/14/93
  4762. I’m trying to use the ICMP echo request function described on page 88 of the MacTCP Developer’s Kit 1.1 manual to 'ping' a TCP host before trying to open a connection. The problems I’m having seem centered around the ICMPEchoNotifyProc. If I declare the proc as 
  4763.     pascal void MyEchoNotifyProc (struct ICMPParamBlock *iopb)
  4764. the proc gets called and the ICMPParamBlockPtr is valid. But after the proc returns, my Macintosh crashes. Can you give me any suggestions as to how to make this puppy work?
  4765. ___
  4766. You’ve found a “bug” in the manual. The ICMPEchoNotifyProc is actually defined as:
  4767.     typedef void (*ICMPEchoNotifyProc) (struct ICMPParamBlock *iopb);
  4768. The definition is correct in <MiscIPPB.h>. Note that in this definition, the proc uses C, not Pascal calling conventions. In C, the caller removes the parameters from the stack, not the callee, so since your routine has already removed the parameters before returning, they are removed twice, corrupting the stack. Changing your procedure to use C calling conventions should fix your problem.
  4769. MacTCP 1.1 & 1.0.1 compatibility
  4770. Date Written:  2/13/92
  4771. Last reviewed:  8/1/92
  4772. We have implemented a TCP/IP product using MacTCP Development Kit  version 1.1. If MacTCP version 1.0.1 is installed, will there be any compatibility problems with our implementation.?
  4773. ___
  4774. There are only a very few new calls in MacTCP 1.1 that aren’t in the 1.0.1 driver. Among these are:
  4775. • Name resolver HInfo and MXInfo calls
  4776. • UDP multi-port sends and receives
  4777. • ICMP echo protocol support
  4778. As long as you’re not using any of these features, any program developed for MacTCP 1.1 will work with 1.0.1.
  4779. MacTCP 1.1 header file incompatibilities and fixes
  4780. Date Written:  9/30/91
  4781. Last reviewed:  8/1/92
  4782. MacTCP 1.1, Apple’s System 7-compatible version of MacTCP, fixes several problems in earlier releases, but doesn’t address several header file incompatibilities. This short note outlines the MacTCP 1.1 header file problems, but it does not include the fixes. Patches in the form of MPW “compare” output are available on Apple’s latest Developer CD Series disc. The new headers are available as part of the “MacTCP Developers’ Kit,” available from APDA (part #M0704/C).
  4783. Each header problem is described below, organized by file(s) containing the problem and classified as a general bug or shortcoming, a Think C incompatibility, or a  C++ incompatibility. NOTE: The changes have not been thoroughly tested, so use them cautiously.
  4784. Problems affecting all header files:
  4785. • General problem: Each header file is missing the
  4786.     #ifdef __cplusplus
  4787.     extern "C" {
  4788.     #endif
  4789. and
  4790.     #ifdef __cplusplus
  4791.     extern "C" {
  4792.     #endif
  4793. which are necessary for C++ unmangling.
  4794. • General problem: There are no #ifdefs to prevent including a file multiple times, as in other Apple headers. This was fixed by adding the following to each of the header files:
  4795.     #ifndef __MACTCPCOMMONTYPES__
  4796.     #define __MACTCPCOMMONTYPES__
  4797.     ...
  4798.     #endif
  4799. where “MACTCPCOMMONTYPES” is replaced by the name of the header file.
  4800. • Think C problem: Think C before 5.0 does not support pascal typedefs, which MacTCP makes use of, so #ifdef THINK_C was added in several instances to declare these pascal typedef functions as type ProcPtr.  This fixes the problem.
  4801. GetMyIPAddr.h problem:
  4802. • General problem: ParamBlockHeader is used as a #define here, conflicting with its use in <Files.h>. The solution is to change the name of the #define to IPParamBlockHeader.
  4803. MiscIPPB.h problems:
  4804. • General problem: ParamBlockHeader is used as a #define here, conflicting with its use in <Files.h>. The solution is to change the name of the #define to GetIPParamBlockHeader.
  4805. • General problem: The structure IPParamBlock is defined in this file with a different definition from the one in GetMyIPAddr.h. The solution is to change the name of the struct.
  4806. • General problem: AppleTalk.h is required for successful compilation. Code was added to include this if it has not already been included.
  4807. • General problem: icmpEchoTimeoutErr is defined in MacTCPCommonTypes in addition to being defined in MiscIPPB.h. Solution is to remove its definition here.
  4808. AddressXLation.h problems:
  4809. Think C incompatibility: The “int” type is used within the “hostInfo” structure definition.  The default size of an int is different from Think to MPW.  In all cases, int in the MacTCP headers should be changed to long.
  4810. • Think C incompatibility: The returnRec struct uses an int. Fix is to change to a long as above.
  4811. • Think C incompatibility: The CloseResolver() prototype is defined with an empty parameter list, not with a void parameter list. Think C requires the void to consider the definition a prototype. The fix is to add the void keyword as the function parameter list.
  4812. • C++ incompatibility: The cacheEntryRecord struct uses a variable named “class”. This causes major problems with C++ compilers, since the class keyword takes on a different meaning in this instance. The fix is to change this to “cacheClass.”
  4813. dnr.c problems:
  4814. • General/Think C problem: The typedef for OSErrProcPtr was incomplete, causing ambiguity for argument casting. This was changed to "typedef OSErr (*OSErrProcPtr)(long,...);" to make sure the first parameter to the name resolver calls is passed as a long.
  4815. • Think C incompatibility: Defines in Think default to short, not long, so all name resolver calls are made incorrectly. This is fixed by the typedef in above, but Think 4.0.5 does not recognize partial prototypes correctly. The fix is to add a “L” to the end of each of the name resolver command #defines.
  4816. • Think C incompatibility: The MXInfo() procedure has an extra semicolon after the trailing brace “};” which causes a syntax error with the Think C compiler. The semicolon was removed to fix the problem.
  4817. No Pascal headers for MacTCP
  4818. Date Written:  3/19/92
  4819. Last reviewed:  6/14/93
  4820. I want to access MacTCP in a Pascal program. Do you have the C parameter block definitions available as Pascal records or will I have to do my own translation?
  4821. ___
  4822. Unfortunately, Pascal header files and interfaces are not available for MacTCP. If you want to use Pascal, you’ll have to translate the interfaces.
  4823. One problem you will run into is that all MacTCP routines and callbacks (those in dnr.c/dnr.o, for example) use C calling conventions. You’ll still be able to call the dnr routines by declaring them as external C functions, as described in the MPW Pascal documentation, but you’ll still have to write any callback functions in C or Assembler, since the Pascal compiler can only call a function using C conventions, but you can’t declare a Pascal function to have C conventions.
  4824. X-Ref:
  4825. MacTCP Programmer’s Guide, Chapter 4, page 47
  4826. MacTCP Type of Service documentation fix
  4827. Date Written:  4/21/92
  4828. Last reviewed:  7/13/92
  4829. Are MacTCP’s Type Of Service (Reliability, Low Delay and Thruput) bit settings swapped in the documentation?
  4830. ___
  4831. The bit settings in the MacTCP programmer’s documentation are reversed for the Type of Service constants. This will be fixed in a future version of the manual. The bit settings should be as follows:
  4832.             Type of Service Byte (3-bit field)
  4833.                 Bit 0 set for low delay
  4834.                 Bit 1 set for high reliability
  4835.                 Bit 2 set for high throughput
  4836. If you wish to correct these settings they can be found on page 35 of the MacTCP Programmer's Guide.
  4837. MacTCP ULP timeout documentation fix
  4838. Date Written:  5/5/92
  4839. Last reviewed:  7/13/92
  4840. In the MacTCP Developer’s Kit (Version 1.1) there is a ULP timeout action field which is used in several PowerBook calls to MacTCP. For some calls, zero indicates an abort and nonzero indicates a report. TCPSend, TCPClose and TCPStatus are this way. For other calls, the reverse is documented (0 indictes report and 1 indicates abort). TCPActiveOpen and TCPPassiveOpen are this way. Can I believe the documentation or are there errors in it ? If there are errors, what is the correct way it should be ?
  4841. ___
  4842. According to the MacTCP source code, and you’re right, the documentation is incorrect. For each of the calls with a ULP timeout action, the correct values are:
  4843.     1 = abort
  4844.     0 = report only
  4845. Macintosh Communications Toolbox MacTCP tools
  4846. Date Written:  6/10/92
  4847. Last reviewed:  9/15/92
  4848. My application uses the Macintosh Communications Toolbox and ADSP to connect to network services. What software do I need to get to make the same connections using TCP/IP? MacTCP or other recommendations?
  4849. ___
  4850. Apple only makes one MacTCP Communications Toolbox tool that works specifically with MacX and TCP/IP (the TCP Tool). This tool is not supported for use by third party developers. For CTB/MacTCP connection tools which are supported, you need to get a third-party CTB MacTCP tool. These are available from several vendors. For example, TCPack from ASC (Advanced Software Concepts) is a set of Connection Tools designed to allow simultaneous TCP/IP connections using Apple’s MacTCP driver. All Apple’s terminal tools (asc3270, asc5250, …), the Apple standard terminal tools (TTY, VT100, VT320), as well as several third-party terminal tools can be used to enter terminal sessions with TCPack. TCP/Tools from InterCon Systems is another package which allows you to use existing CTB applications to log onto Unix workstations using your LocalTalk or EtherTalk network.
  4851. NW 560 - Macintosh Protocol Package Q&As
  4852. Networking    
  4853. Revised by:    Developer Support Center    September 1993
  4854. Written by:    Developer Support Center    October 1990
  4855. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4856. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4857. New Q&As this month:
  4858. Retries and tickle mechanism for nonAppleShare connections
  4859. Retries and tickle mechanism for nonAppleShare connections
  4860. Date Written:  12/28/92
  4861. Last reviewed:  3/1/93
  4862. We’re experiencing time-outs in the .MPP driver communications between our non-AppleShare server and applications that talk to it, when the connection is low-speed (for example, an AppleTalk Remote Access connection). We have no problems over local area nets or with AppleShare connected over our low-speed connection. What values should we use for the ATP timeOutVal and retryCount?
  4863. ___
  4864. The reason you don’t see problems with AppleShare connections is that AppleShare uses the AppleTalk Filing Protocol (AFP) and AFP is built on the AppleTalk Session Protocol (ASP). ASP uses an infinite retry count on its ATP transactions and a tickle mechanism to detect broken session connections. If ASP’s tickle mechanism finds the session connection is dead, it kills all outstanding asynchronous ATP calls with PKillSendReq and PKillGetReq. ASP clients don’t have to worry about time-out conditions except when the network connection fails.
  4865. The AppleShare workstation determines the timeOutVal to pass to AFP/ASP by using the Apple Echo Protocol. Here’s how you could use the echo protocol to determine the timeOutVal for your program:
  4866. 1.    Send the other end of the new connection a full-size (586-byte) packet to the echo socket.
  4867. 2.    Wait for up to 10 seconds for the echo packet to come back. This should be enough time to send a full-size packet both ways at 1200 bps (slower than any connection you’d hope to encounter on an AppleTalk network).
  4868. 3.    If the echo packet isn’t back in 10 seconds, assume the packet was lost either going to or coming from the other end and use a default retry time of 4 seconds (this is what AppleShare uses as a default when its echo packet is lost—it’s generally a good value for LocalTalk).
  4869. 4.    If the echo packet is back within 10 seconds, multiply the turnaround time by 4.5 (enough time to transfer nine full-size packets).
  4870. 5.    Add the maximum amount of latency you expect the responding side of the connection to have between receiving a request and sending the response (you’ll have to determine this value by running your code on a slow system).
  4871. 6.    If the calculated value ( (echo time * 4.5) + latency ) is greater than 2 seconds, use it. Otherwise use a minimum default retry time of 2 seconds. The reason for keeping the minimum above a certain level is to minimize network traffic.
  4872. We recommend building a session protocol something like ASP on top of ATP so that you can use infinite retries and let a tickle mechanism tear down a broken connection. A tickle mechanism is also easy to implement. For example, to implement a tickle mechanism like the one AppleTalk protocols use, just start a VBL task with a vblCount of 2 minutes (120 ticks) on both ends of the connection. Every time you receive a packet of any kind from the other side of the connection, reset the vblCount to 2 minutes again. If the VBL task ever gets called, the connection was broken. To send the tickle packets, just call PSendRequest (or PNSendRequest) to send a small tickle request with an infinite retry count and a retry period of 30 seconds. Whenever you receive a tickle packet from the other side of a connection, simply ignore it (if you don’t respond, ATP will keep retrying every 30 seconds, which is what you want).
  4873. If you don’t want to use a tickle mechanism, you’ll have to decide how many times you want ATP to retry. The value you use should balance how long you want a user to wait for something to happen and how reliable the user’s network is at delivering packets — something that isn’t at all easy to determine.
  4874. For more information, see the Macintosh (Networking) Technical Note “AppleTalk Timers Explained.”
  4875. MPP stands for Macintosh Protocol Package handler
  4876. Date Written:  2/28/92
  4877. Last reviewed:  2/28/92
  4878. What does “MPP” stand for? We know it’s a lower-level driver that contains code to implement ALAP (Link Access Protocol), DDP (Datagram Delivery Protocol), NBP (Name Binding Protocol), and RTMP (Routing Table Maintenance Protocol) stuff, but we’re curious to the point of not being able to do any work :) Macintosh Packet Protocol? Multiple Problem Protocol?
  4879. ___
  4880. MPP stands for Macintosh Protocol Package handler. XPP stands for eXtended Protocol Package handler; ATP stands for AppleTalk (originally AppleBus) Transaction Protocol handler; DSP is Data Stream Protocol handler; LTM is Link Tool Manager; and MNP is Microcom Networking Protocol, implemented by AppleTalk Remote Access across the remote link. Hope you can get some work done now ;)
  4881. RAM-based AppleTalk driver fixes Mac Plus PNSendRequest error
  4882. Date Written:  1/1/91
  4883. Last reviewed:  1/1/91
  4884. I get an odd address error when using PNSendRequest on the Macintosh Plus. The Macintosh Plus has version 19 of the .MPP driver. Is there is an INIT or something that patches the older Macintosh models with the newer drivers?
  4885. ___
  4886. Inside Macintosh suggests checking the .MPP driver version to see if the new driver is available (version >= 48).
  4887. You need the RAM-based AppleTalk drivers on the older Macintosh models to use the calls documented in Inside Macintosh Volume V. The RAM-based AppleTalk driver is available as an AppleTalk System file, and you need to place it in the System Folder of your Mac Plus.
  4888. X-Ref:
  4889. “The AppleTalk Manager,” Inside Macintosh Volume V
  4890. PKillNBP aKillQEl pointer
  4891. Date Written:  6/12/92
  4892. Last reviewed:  9/15/92
  4893. Where can I get the Q element pointer for a PLookupName call in order to call PKillNBP?
  4894. ___
  4895. The pointer that you pass in the parameter block to PKillNBP, is the pointer to the parameter block of the outstanding lookup request. If several lookup requests have been made asynchronously, and are outstanding, then you would take the pointer to each parameter block and issue separate PKillNBP calls for each lookup to kill the request on.
  4896. Each asynchronous lookup request along with other asynchronous requests to the drivers get queued for processing. The KillNBP request takes the pointer to the parameter block of the outstanding request and searches through the driver queue, looking for a match. When a match is found, the request is dequeued and the driver notified of the action. If the request has already been dequeued—for example, if the original lookup request was completed while the PKillNBP was made—a cbNotFound error (error -1102) will be returned.
  4897. NW 565 - Name Binding Protocol Q&As
  4898. Networking    
  4899. Revised by:    Developer Support Center    September 1993
  4900. Written by:    Developer Support Center    October 1990
  4901. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4902. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4903. Macintosh NBPLookup badUnitErr conditions
  4904. Date Written:  11/14/90
  4905. Last reviewed:  2/8/91
  4906. Why am I getting a badUnitErr as a result code from NBPLookup? This error is not listed as a result code for NBPLookup, nor anywhere in the AppleTalk Manager.
  4907. ___
  4908. You’re probably getting the badUnitErr result because you don’t have the AppleTalk drivers open. Since AppleTalk calls are made to a device driver (the AppleTalk driver), you can get back general operating system errors from the driver.
  4909. See the Macintosh Technical Note “Opening AppleTalk” for a description of how to open the AppleTalk drivers. 
  4910. AppleTalk 56 NBP reply packet entity field checks
  4911. Date Written:  6/14/91
  4912. Last reviewed:  6/14/93
  4913. As stated in Inside AppleTalk, each entity field in an NBP reply packet can be a maximum of 32 characters. In previous versions of AppleTalk, no range checking was done on entity field lengths, and often names that were too long were used, which eventually caused a crash somewhere else in the protocol stack.
  4914. Likewise, a null character in the object field of an entity has never been OK; it just happened to work because no range checking was done. (The only place that a null can legally be used in an NBP tuple is in the zone name field of an NBP LkUp, FwdReq, or BrRq packet; see page 7-17 of Inside Appletalk for more information.)
  4915. Now, under Appletalk 56, a range check is done on each entity field to ensure that the length is legal (1<=length<=32). When it finds a packet that contains a “corrupt” entity name, that packet is discarded.
  4916. Name Binding Protocol (NBP) interval and count fields
  4917. Date Written:  9/13/91
  4918. Last reviewed:  10/8/91
  4919. Is there a limit on the values set in the Name Binding Protocol (NBP) interval and count fields when used with PLookupName and PConfirmName calls? How do the interval and count work? If a device is not on the network and I send a PLookupName with interval = 20 and count = 20, will I wait 400 seconds before PLookupName returns?
  4920. ___
  4921. Since the interval and count parameters for NBP calls are both 1-byte, the values used are limited to the range of 0-255 ($00-$FF). Here’s what the values do:
  4922. •    interval = retransmit interval in 8-tick units. This value is used to set up a VBL task. A value of 0 should not be used because that would mean the VBL task would never be executed and would be removed from the VBL queue.
  4923. •    count = total number of transmit attempts. Each time the interval timer expires, this value is decremented by 1. When it reaches 0, the NBP call completes. So if a value of 0 is used, the packet will be retransmitted 255 times (or transmitted 256 times).
  4924. Three things can happen to make the LookupName, RegisterName, or ConfirmName calls complete:
  4925. •    PKillNBP can be called to abort one of the calls (see Inside Macintosh Volume V, page 519).
  4926. •    maxToGet matches are returned or the return buffer is filled. Here’s how this works: Each time an NBP lookup reply (LkUp-Reply) packet is received, an attempt is made to add all the NBP tuples found in that LkUp-Reply packet to the return buffer. If all the tuples cannot be added to the buffer because there isn’t enough room, the call completes with as many tuples as could fit and the numGotten field will contain the number of matches in the buffer. If all the tuples from the LkUp-Reply packet are added to the buffer, numGotten (the number of matches in the buffer) is compared to the value passed in the maxToGet field. If numGotten is greater than or equal to maxToGet, the call completes and the numGotten field will contain the number of matches in the buffer. Since the buffer can fill before maxToGet matches are received and since LkUp-Reply packets can return multiple tuples, you may get more or fewer matches than you asked for with maxToGet.
  4927. •    The count is decremented to 0. You can use this equation to determine how long the call would take to complete this way:
  4928.      IF count = 0 THEN count := 256;
  4929.      TimeToCompleteInTicks := count * interval * 8;
  4930. The RegisterName and ConfirmName calls always complete after they receive the first LkUp-Reply packet to their request, so you could look at them as always having a maxToGet of 1 (maxToGet is not one of the parameters for those two calls).
  4931. AppleTalk PLookupName interval and retry values
  4932. Date Written:  1/6/92
  4933. Last reviewed:  1/27/92
  4934. What are recommended values for retry interval and retry count when using the AppleTalk NBP call PLookupName on a complicated internet?
  4935. ___
  4936. You might want to start with the NBP retry interval and retry count values Apple uses for its Chooser PRER and RDEV device resource files. The Chooser grabs these values from the PRER’s or RDEV’s GNRL resource -4096:
  4937.     Device                      Interval  Count
  4938.     --------------------------  --------  -----
  4939.     LaserWriter                   $0B      $05
  4940.     AppleTalk ImageWriter         $07      $02
  4941.     AppleShare                    $07      $05
  4942.     If no GNRL resource           $0F      $03
  4943. Apple’s engineering teams found these values to work well in most situations.
  4944. The count value should be based on how likely it is for the device to miss NBP lookup requests. For example, the AppleTalk ImageWriter has a dedicated processor on the LocalTalk option card just to handle AppleTalk, so its count value is low; most Macintosh models and LaserWriter printers depend on their 680x0 processor to handle AppleTalk along with everything else in the system (the Macintosh IIfx and Macintosh Quadra models are exceptions to this), so their count value is higher.
  4945. The interval value should be based on the speed of the network and how many devices of this type you expect there to be on the network. On a network with very slow connections (for example, one using a modem bridge), or in cases where there are so many devices of a particular type that lots of collisions occur during lookups, the interval value should be increased.
  4946. Apple puts these values in a resource because not all networks and devices are alike. You should do the same (put your interval and count in a resource so that it can be configured).
  4947. Don’t access the MPW NBP EntityName field directly
  4948. Date Written:  1/1/91
  4949. Last reviewed:  6/14/93
  4950. When I fill in the fields of MPW’s Name Binding Protocol (NBP) EntityName structure, AppleTalk doesn’t recognize the entity, even though I know it’s out there. What’s going on?
  4951. ___
  4952. The real definition of EntityName is 3 PACKED strings of any length (32 is an example). No offsets for Asm are specified since each string address must be calculated by adding the length byte to the last string pointer. In Pascal, String(32) will be 34 bytes long since fields never start on an odd byte unless they are only one byte long, so this will generate correct-looking interfaces for Pascal and C, but the interfaces will not be the same. This is OK since they are not used.
  4953. The point is that you should never try to access the fields of the EntityName field directly. The only reason the type is defined at all is so that you can allocate EntityName variables that will hold the largest possible EntityName. To fill in an EntityName record, you call the NBPSetEntity routine.
  4954. NW 570 - Printer Access Protocol Q&As
  4955. Networking    
  4956. Revised by:    Developer Support Center    September 1993
  4957. Written by:    Developer Support Center    October 1990
  4958. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  4959. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  4960. Monitoring PAP packets with AppleTalk Peek
  4961. Date Written:  8/7/90
  4962. Last reviewed:  8/30/90
  4963. Are there hardware or software tools for monitoring AppleTalk Printer Access Protocol (PAP) packets in some direct way?
  4964. ___
  4965. A tool called “AppleTalk Peek” allows you to monitor packets that are being sent over AppleTalk. It is available on the AppleLink and on the latest Developer CD Series disc. You can find the tool via the following path: Storage and Communication Folder : Network Folder : AppleTalk Tools Folder. This tool might enable you to determine experimentally, PostScript handle sizes that work best for your application.
  4966. Using PAP & code for finding printer driver under System 7
  4967. Date Written:  6/6/91
  4968. Last reviewed:  8/1/91
  4969. Is there any documentation or sample code on the Printer Access Protocol (PAP), besides Inside AppleTalk and MacTutor’s sample? Or is there a better way to shove 1 MB and larger files down the pipe to a PostScript device?
  4970. ___
  4971. The question that you ask has become a popular one these days; it seems that a lot of people are writing PAP programs. Unfortunately, there isn’t really a clean-cut answer. There are several options:
  4972. 1) The code that appeared in MacTutor seems to work just fine. Of course, it is unsupported by Apple and it may very well break under a future system software release. It is definitely the quickest way to get a PAP-based program coded.
  4973. 2) You could write your own PAP interfaces. This is a very time consuming operation, but it also most likely not to break under future systems. Other companies have done it, and it is fairly straightforward.
  4974. 3) Through software licensing, you can license a library named papworkstation.o. It is a library only, with little or no documentation, and it is unsupported. It is, however, used by several third parties, and it works OK.
  4975. In case you do use the MacTutor code, the following example shows a method for finding the printer driver under System 7:
  4976. FUNCTION GetPAPDriver: BOOLEAN;
  4977. VAR
  4978.   theResFile:        INTEGER;
  4979.   theWorld:        SysEnvRec;
  4980.   theError:        OSErr;
  4981.   DoinFolders:    BOOLEAN;
  4982.   myFeature:        LONGINT;
  4983.   sysVRefNum:        INTEGER;
  4984.   sysDirID:        LONGINT;
  4985.   gotDriver:        BOOLEAN;
  4986.   numStr:            Str255;
  4987. BEGIN
  4988.   gotDriver := TRUE;
  4989.   DoinFolders := FALSE;
  4990. (*---------------------  The 7.0 Way!   --------------------------*)
  4991.   IF GestaltAvailable THEN BEGIN
  4992.     theError := Gestalt(gestaltFindFolderAttr, myFeature);
  4993.     IF theError = noErr THEN BEGIN
  4994.       DoinFolders := BitTst(@myFeature, 31-gestaltFindFolderPresent);
  4995.       IF DoinFolders THEN BEGIN
  4996.           theError := FindFolder(kOnSystemDisk, kExtensionFolderType, 
  4997.                                  kDontCreateFolder, sysVRefNum, sysDirID);
  4998.           IF theError <> noErr THEN BEGIN
  4999.               DebugStr('FindFolder err');
  5000.               gotDriver := FALSE;
  5001.           END;
  5002.       END;
  5003.     END;
  5004.   END;
  5005.   (* If FindFolder was not available, use good ol' SysEnvirons (thanks Jim)*)
  5006.   IF NOT DoinFolders THEN BEGIN
  5007.     (* No FindFolder!  Gotta do it the old way... *)
  5008.     theError := SysEnvirons(1, theWorld);
  5009.     IF theError = noErr THEN
  5010.       sysVRefNum := theWorld.sysVRefNum
  5011.     ELSE
  5012.       gotDriver := FALSE;
  5013.   END;
  5014. (*------------------------------------------------------------------*)
  5015.   (* Okay, at this point we should have found the folder where the drivers *)
  5016.   (* are. If we  are running under System 7.0, this folder will be the     *)
  5017.   (* extensions folder in the System folder. If we are pre-7.0, this will  *)
  5018.   (* be the System folder. If FindFolder was available, then we have to    *)
  5019.   (* use HOpenResFile because FindFolder uses dirIDs. If we just used      *)
  5020.   (* SysEnvirons (ie. pre 7.0), then we can use OpenRFPerm.                *)
  5021.   IF gotDriver THEN BEGIN
  5022.     IF DoinFolders THEN
  5023.       theResFile := HOpenResFile(sysVRefNum, sysDirID, driverName, fsRdPerm)
  5024.     ELSE
  5025.       theResFile := OpenRFPerm(driverName, sysVRefNum, fsRdPerm);
  5026.     theError := ResError;
  5027.     IF theError = noErr THEN BEGIN
  5028.       driverCode := GetResource('PDEF', 10);
  5029.       HNoPurge(driverCode);
  5030.       DetachResource(driverCode);
  5031.       IF ResError = noErr THEN BEGIN
  5032.         LWName := StringHdl(GetResource('PAPA', -8192));
  5033.         DetachResource(Handle(LWName));
  5034.         CloseResFile(theResFile)
  5035.       END ELSE
  5036.           gotDriver := FALSE;
  5037.     END ELSE BEGIN
  5038.       NumToString(theError, numStr);
  5039.       DebugStr(numStr);
  5040.       gotDriver := FALSE;
  5041.     END;
  5042.   END ELSE
  5043.     gotDriver := FALSE;
  5044.   GetPAPDriver := gotDriver;
  5045. END; (* GetPAPDriver *)
  5046. NW 575 - Routing Table Maintenance Protocol Q&As
  5047. Networking    
  5048. Revised by:    Developer Support Center    September 1993
  5049. Written by:    Developer Support Center    October 1990
  5050. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  5051. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  5052. Receiving RTMP packets from a generic router
  5053. Date Written:  4/22/91
  5054. Last reviewed:  6/14/93
  5055. I’m trying to receive the periodic Routing Table Maintenance Protocol (RTMP) packets sent out from a generic router. The only solution so far is to close down the Link Access Protocol (LAP) handlers and install my own. However, when I’m finished, I must restart AppleTalk when my program exits. Is there an alternative solution?
  5056. ___
  5057. You’ve hit upon a side effect of the AppleTalk architecture. It’s understandable that being only a listener, that you would simply want to attach yourself into the LAP chain without shutting down AppleTalk. Your findings are correct though—you would need to shut down the LAP handler and install one of your own. This would require restarting AppleTalk when your program exits.
  5058. You’d find that EtherPeek, a commercially available software sniffer works similarly. This has the ramifications of complicating the process by restarting AppleTalk with the desired connection method. It also limits compatibility with Apple cards and those from other vendors you select to support.
  5059. Multicast addresses for zone names hashed to same index value
  5060. Date Written:  3/3/92
  5061. Last reviewed:  6/14/93
  5062. What’s the strategy for assigning a multicast address if two different zone names hash to the same index value? How do two different routers synchronize the multicast address assignment in the case of hash synonyms?
  5063. ___
  5064. It’s quite possible that two zone names will hash to the same index. Networks which have zone names that hash to synonyms will have the packets resolved at the receiving nodes. Packets that get delivered to the wrong zone because of identical multicast addresses will be handled by NBP (Name Binding Protocol), which will see that the destination zone name is different if the target zone is the zone synonym.
  5065. Start & end for extended networks with single number for range
  5066. Date Written:  3/3/92
  5067. Last reviewed:  6/14/93
  5068. If a network is assigned a single network number for a network number range—for example, 3—how is the network number range start and end represented? It is 3-3 or 3-0 or is it anything else?
  5069. ___
  5070. On an extended network type such at TokenTalk or EtherTalk, a network range of a single network number is entered as both the start and end of the range. For example, a network range of 3 is such that netLo is 3 and netHi is also 3.
  5071. Phase 2 routers must support Split Horizon technique
  5072. Date Written:  3/3/92
  5073. Last reviewed:  6/14/93
  5074. RTMP data packets sent by all routers on an internet use the Split Horizon technique or the No-Split Horizon. Does it matter if different routers use different techniques?
  5075. ___
  5076. The AppleTalk router, version 2.0, implements the Split Horizon technique. All Phase 2 routers MUST implement the Split Horizon technique for compatibility with AppleTalk. For a description of the Split Horizon technique, refer to Inside AppleTalk, 2nd ed., 5-11.
  5077. AppleTalk routers and Route Data Request (RDR) packets
  5078. Date Written:  3/3/92
  5079. Last reviewed:  6/14/93
  5080. Does an AppleTalk router initiate a Route Data Request (RDR) packet? If so, when?
  5081. ___
  5082. A router is free to send a Route Data Request packet at any time. A particularly good time to send an RDR packet is when a router has not heard from another router in some time.
  5083. NW 580 - Token Ring Q&As
  5084. Networking    
  5085. Revised by:    Developer Support Center    September 1993
  5086. Written by:    Developer Support Center    October 1990
  5087. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  5088. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  5089. New Q&As this month:
  5090. NetCopy procedure replaces TokenTalk CopyNuBus
  5091. NetCopy procedure replaces TokenTalk CopyNuBus
  5092. Date Written:  9/23/92
  5093. Last reviewed:  6/14/93
  5094. The TokenTalk Programmer’s Guide describes a routine called CopyNuBus. This routine is not in the IPCGlue.o file dated 3/4/92 that I got off a Developer CD. Has this routine been replaced by something else, and if so, what is the calling sequence of the new routine?
  5095. ___
  5096. The TokenTalk Programmer’s Guide hasn’t been updated to reflect the fact that the CopyNuBus routine has been replaced by the more robust NetCopy procedure. The prototype for the NetCopy routine is
  5097. short  NetCopy(tid_type srcTID, void *srcAddress, tid_type dstTID, void *dstAddress, 
  5098.                unsigned long bytecount);
  5099. Note the addition of the source and the destination TIDs. NetCopy will copy from a source virtual address to a target virtual address and is a safe way to move data across the NuBus. Both the source and destination virtual addresses can be paged out to disk in a VM environment. NetCopy will cause these pages to be brought back into memory before the copy is performed. A result of zero is returned if NetCopy is successful.
  5100. This information comes from the A/ROSE Programmer’s Guide. You should get a copy of this guide and referring to it regarding A/ROSE programming questions instead of referencing the TokenTalk Programmer’s Guide. A/ROSE has been a fast evolving piece of software. Always refer to the latest Developer CD for the latest revision.
  5101. TokenTalk LLCBadList and LLCTruncated
  5102. Date Written:  9/24/91
  5103. Last reviewed:  6/14/93
  5104. When a list-directed receive is queued to TokenTalk’s implementation of Logical Link Control (LLC) with a total data size less than the active frame size, LLCBadList is returned when the receive completes. If a nonlist-directed receive is used, and the buffer size is less than a frame size, LLCTruncated is returned. Why aren’t the same error codes (LLCTruncated) returned as the condition is the same?
  5105. ___
  5106. The LLCBadList error results because of an undocumented limitation imposed on the number of lists allowed in a list-directed receive. It’s likely that you’ve specified a list array with greater than eight elements. When the list is passed to LLCReceive, a check is made on the list array if one is used. If more than eight elements are in the list, the LLCBadList error is returned immediately with no processing of the incoming data.
  5107. On the other hand, if a nonlist-directed receive is used, the LLCReceive call is queued into the task list. The present TokenTalk LLC implementation doesn’t support partial reads of large data frames, so if it turns out that the buffer size is smaller than the frame size, only the information that fits into the buffer is returned. The remaining information is discarded. The error condition LLCTruncated is returned to indicate that this event occurred.
  5108. How to get burned-in & locally administered Token Ring addresses
  5109. Date Written:  12/11/91
  5110. Last reviewed:  12/12/91
  5111. How can I read the “burned-in” address from the TokenTalk NB card? How about for the locally administered address?
  5112. __
  5113. To access the burned-in address, use the TTGetDefaultParms selector when calling the TTUtil function pointer. On return, the record structure, TRInit, will contain the value of the “burned-in” address in the field NodeAddr. Use the TTGetBootParms selector to obtain the equivalent information from the TokenTalk Prefs file, that information which has been locally set.
  5114. Note the following #defines to include in your TTUtil.h header file:
  5115. #define  TTGetDefaultParms  10  /* Return default TRInit parameters */
  5116. #define  TTGetBootParms  11 /* Return TRInit parameters to use on next boot */
  5117. /*
  5118.  *  The TTGetDefaultParms and TTGetBootParms returns a pointer to the 
  5119.  * parameter structure, or zero if no parameters could be returned. The 
  5120.  * parameter structure returned should be released by the caller by calling 
  5121.  * DisposPtr when done.
  5122.  */
  5123. TokenRing NB 4/16 Card and “promiscuous” mode support
  5124. Date Written:  12/6/91
  5125. Last reviewed:  6/14/93
  5126. Can the IBM chipset which is on Apple’s new TokenRing NB 4/16 Card be programmed to go into “promiscuous” mode? I would like to write a Sniffer application which runs on the new card.
  5127. ___
  5128. At present, the present design of the IBM mini-card is such that the chipset cannot be programmed to run in promiscuous mode.  A request has been submitted to IBM to allow the chipset to be placed into this mode.  There is no date as to when such functionality will become available.
  5129. TokenTalk maximum transmit buffer size
  5130. Date Written:  12/19/91
  5131. Last reviewed:  6/14/93
  5132. In reviewing the 'llcp' resource for the new TokenTalk 4/16 NuBus card, I noticed that the maximum receive frames size has been changed to 0x1170 or 4464 bytes. If this is correct, what is the maximum transmit size (used to be 1509 bytes)?
  5133. ___
  5134. The change is for real. It was implemented at the request of developers like yourself. The change affects all Apple’s TokenTalk products provided that TokenTalk Prep 2.4 is present.
  5135. The maximum transmit buffer size depends on the 'llcp' resource in the TokenTalk Prep or (TokenTalk Prefs file if one is available). Within the 'llcp' resource is a buffer size value used to initialize the size of the receive/transmit buffers. For file versions 2.2 and earlier, the factory limit was 1509 bytes. For TokenTalk Prep version 2.4, the buffer size is set to 4464 bytes.
  5136. NW 585 - X.25 and X.400 Q&As
  5137. Networking    
  5138. Revised by:    Developer Support Center    September 1993
  5139. Written by:    Developer Support Center    October 1990
  5140. This Technical Note contains a collection of Q&As relating to a specific topic—questions you’ve sent the Developer Support Center (DSC) along with answers from the DSC engineers. While DSC engineers have checked the Q&A content for accuracy, the Q&A Technical Notes don’t have the editing and organization of other Technical Notes. The Q&A function is to get new technical information and updates to you quickly, saving the polish for when the information migrates into reference manuals.
  5141. Q&As are now included with Technical Notes to make access to technical updates easier for you. If you have comments or suggestions about Q&A content or distribution, please let us know by sending an AppleLink to DEVFEEDBACK. Apple Partners may send technical questions about Q&A content to DEVSUPPORT for resolution.
  5142. Which A/ROSE version to use
  5143. Date Written:  6/2692
  5144. Last reviewed:  6/14/93
  5145. What should I be doing with A/ROSE versions? My application links with X.25_Interface_Library.o, IPCGlue.o, and FSDES.o. Should I be using the latest IPCGlue.o that is on the Developer CD, or should I use the one that came with the X.25 Developers Kit? Also what about A/ROSE itself? Can I safely replace the existing one in my Extensions folder with the latest one from the CD? If I do should I relink the app with the corresponding IPCGlue.o? What about the MacX25 Admin? Will it be happy with the latest copy of A/ROSE in the Extensions folder? My code resources also link with IPCGlue.o. I assume I should link the code resources and app with the same IPCGlue.o, right?
  5146. ___
  5147. Changes to A/ROSE are typically made to A/ROSE itself. In general, you should follow the guideline that you describe—link with the library file for the version of A/ROSE you plan to ship with. Interestingly, the A/ROSE IPCGlue.o file shipped with MacX25 1.0.1 is still fine for linking with. You should also relink your application with the (MacX25 1.1) X.25_Interface_Library.o as there are a number of memory management bugs fixed between 1.0.1 and 1.1, some of which caused system crashes.
  5148. Over the past several years, new releases of A/ROSE have been made to fix bugs and to support new hardware. If you plan to be compatible with new CPUs, you might want to supply the latest release of A/ROSE.
  5149. Locking X.25 segments
  5150. Date Written:  6/2692
  5151. Last reviewed:  6/14/93
  5152. Are there any of the X.25 segments from X25_Interface_Library.o that need to be locked or should be specified as resident in my application’s 'res!' resource? In, particular I am wondering about the segment X25_VBL.
  5153. ___
  5154. The X25_VBL segment contains code that is executed at interrupt time, and the rules for dealing with interrupt driver code should be followed—that is, the VBL code and VBL task record should be locked down.
  5155. Segmenting data for X25_Write
  5156. Date Written:  6/2692
  5157. Last reviewed:  6/14/93
  5158. When writing data with the X25_Write routine, I seem to need to break up the data to write according to the current packet size and then make separate calls for each data chunk/packet. I had hoped the X25_Write would have figured that out by itself. Am I missing something? What about when using X25_Read? Should I be reassembling packets with the M_Bit set, into big chunks of data?
  5159. ___
  5160. No, At present, the X25_Write routine does not do anything very useful in the domain of segmentation and reassembly of X.25 data. The routine only handles the segmentation and assembly of one packet’s worth of data. Unfortunately, the same comment applies to the X25_Read routine.
  5161. Depending on A/ROSE to correctly queue a message
  5162. Date Written:  6/2692
  5163. Last reviewed:  6/14/93
  5164. Is it possible to intercept an A/ROSE message from the X.25 server that was destined for the X.25_Interface_Library? The server and the client are running on the same machine, and I connect to the server with X25_Server_Connect(gTcb, connect_via_best).
  5165. ___
  5166. A/ROSE is dependable for delivering messages to your task, that are sent to your task, and not to other tasks. To date, there have not been any problems reported on this subject.
  5167. Translating 8-bit Macintosh text to 7-bit ASCII
  5168. Date Written:   12/20/90
  5169. Last reviewed: 6/24/93
  5170. Is there an Apple-recommended method for converting 8-bit Apple text characters to that which can be sent over 7-bit media while observing X.400 rules, and only submit 7-bit text into the x.400 IA5Text body parts?
  5171. ___
  5172. MacPAD used to support only 7-bit file transfers, but it’s now possible to translate from 8 bit characters to 7 bit.
  5173. Where to find X.400 & X.500 references
  5174. Date Written:  1/23/91
  5175. Last reviewed:  6/14/93
  5176. Where can I find documentation on the X.400 and X.500 electronic-mail standard?
  5177. ___
  5178. There are a few interesting articles about X.400 in the Technical Information Library on AppleLink. One of them mentions that Apple has a forthcoming X.400 solution that is an X.400-compliant MTA (Message Transfer Agent) that runs on any modular Macintosh under System 7. It includes the seven layers of the OSI model. It works either over X.25 (on top of the MacX25 product) or over 802.3. (This is the most used link in the U.S.) It lets Macintosh users gain access to public X.400 networks or to connect to their private X.400 backbone.
  5179. For standards and specifications on X.400 and X.500, check with your local library for an IEEE periodical index. IEEE documents this type of stuff fairly regularly.
  5180. Feasibility of MacX25 AppleTalk internet routers
  5181. Date Written:   3/26/91
  5182. Last reviewed: 6/24/93
  5183. What’s the feasibility of internet routers for AppleTalk networks over MacX25?
  5184. ___
  5185. Internet routers for AppleTalk networks over MacX25 are not only feasible, they’re available. Apple’s internet router 3.0, with the X.25 internet router extension, provides this function.
  5186. Providing general “listeners” on MacX25 servers
  5187. Date Written:  3/26/91
  5188. Last reviewed:  6/14/93
  5189. Is it feasible to develop general “listeners” on the MacX25 servers? This would allow users to connect to MacX25 servers and request specific services to be provided. Other non-Macintosh systems could also communicate with such listeners.
  5190. ___
  5191. MacX25 does indeed provide a listener agent. Please refer to the MacX25 product documentation. If, however, you want to develop your own listener, one could be provided via access to A/ROSE.
  5192. How to increase Macintosh X.25 user list size
  5193. Date Written:  7/25/91
  5194. Last reviewed:  6/14/93
  5195. How do we go beyond the Macintosh X.25 user list entry limit of 256?
  5196. ___
  5197. The size of the X.25 user list can be modified by modifying the 'Maxu' resource in the X.25 Admin program using ResEdit. If you’re using the latest revision of ResEdit version 2.1, a template for the 'Maxu' resource exists to assist with this modification. The other recommended change is to increase the program partition size of X.25 Admin by 32 bytes for each additional user to ensure that there is enough memory to hold all of the names. Note that this change does not increase the number of simultaneous connections.
  5198.  
  5199. .◊#ˇ ˇˇˇˇ#◊†Ç 
  5200. /ZÅ#
  5201.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5202. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5203. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5204. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5205. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5206.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5207. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5208. IR.°dONLNdn<Åh(õZ!NW 1 - AppleShare and Old Finders
  5209. °dONLNd"Ä<èä*
  5210. Networking
  5211. °dONLNd.õ<ßt* Revised by:°dONLNd;õ≈߲(√„
  5212. March 1988°dONLNdFß<≥q(œZ Written by:°dONLNdRßÑ≥«)H
  5213. Bryan Stearns°dONLNd`ß≈≥˛(œ„
  5214. March 1987 fiXfi°dONLNdkÃ<ÿ‡(ÙZTA rumor has been spread that if you use a pre-AppleShare Finder on a workstation to °dONLNdøÃ‡ÿ˛(Ù˛access°dONLNdΔÿ<‰…(ZNAppleShare volumes, you can bypass AppleShare’s “access privilege” mechanisms.°dONLNd<¸Æ*This is not true. Access °dONLNd.Ƹ^)r%controls are enforced by the server, °dONLNdS^¸p)∞not°dONLNdVp¸˛) by the Finder. If you use an°dONLNdt¸<£($Zolder Finder, you are °dONLNd丣˛)gJstill prevented (by the server) from gaining access to protected files and°dONLNd’<¯(0Z'folders; however, you will not get the °dONLNd¸¯˛)º4proper user-interface feedback that you would if you°dONLNd1< …(<ZVwere using the correct Finder: for instance, folders on the server will always appear °dONLNdá… ˛(<Á plain white°dONLNdì <,T(HZ(that °dONLNdô T,˛)Uis, without the permission feedback you’d normally get), and error messages would not°dONLNdÔ,<8¥(TZMbe as explanatory as those from Finders that “know” about AppleShare servers.°dONLNd=\<h¶*0Further Reference: áXá°dONLNdPiNuR+
  5215. •°dONLNdRi`u⁄)AppleShare User’s Guide ¡X¡
  5216. (÷Z!NW 1 - AppleShare and Old Finders(÷1) of 1(ÏZM.NW.AppleShareAndOldFinderˇ°¿Ù%%DSIDICT:_cv
  5217. currentdict /bu known {bu}if
  5218. userdict /_cv known not{userdict /_cv 30 dict put}if
  5219. _cv begin
  5220. /bdf{bind def}bind def
  5221. currentscreen/cs exch def/ca exch def/cf exch def
  5222. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5223. /ss{//cf //ca //cs setscreen}bdf
  5224. /stg{ss setgray}bdf
  5225. /strgb{ss setrgbcolor}bdf
  5226. /stcmyk{ss cvcmyk}bdf
  5227. /min1{dup 0 eq{pop 1}if}bdf
  5228. end
  5229. currentdict /bn known {bn}if
  5230. †øz◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  5231. /ZÅ#
  5232.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5233. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5234. .WIQkWIQk+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5235. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5236. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5237.     l+&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5238. BÄ(Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É°dWORD†ç
  5239. IR.°dONLNdo<Çd(úZ!NW 2 - AppleTalk Interface Update
  5240. °dONLNd"Å<êä*
  5241. Networking°dONLNd-Åê˛)„M.NW.AppleTalkInterfaceUpdate
  5242. °dONLNdKú<®t(ƒZ Revised by:°dONLNdXú≈®˛(ƒ„
  5243. March 1988°dONLNdc®<¥q(–Z Written by:°dONLNdo®Ñ¥«)H
  5244. Bryan Stearns°dONLNd}®œ¥˛(–Ì    July 1987°dONLNdá¿<Ã’(ËZNM.NW.HL.AppleTalk announced that we would be moving to a simplified AppleTalk °dONLNd’¿’Ã˛(ËÛManager°dONLNd›Ã<ÿó(ÙZIinterface. That interface is available now, as part of MPW 2.0 and newer.°dONLNd'‰<´*Documentation for this °dONLNd>‰´·)o?new interface is contained in the AppleTalk Manager chapter of °dONLNd}‰·˛( ˇInside°dONLNdÑ<¸†(ZMacintosh Volume V°dONLNdñ†¸ß)d. °dONLNdò߸˛)FThis technical note contains some of the preliminary documentation for°dONLNdfl¸<Ê($Z[this interface and some useful points about information about it, and AppleTalk in general. 3X3°dONLNd;"<.:*&3The original AppleTalk Pascal Interfaces, known as ,
  5245. Courier°dONLNdn!:-y)˛    ABPasIntf°dONLNdw"y.◊)?, were designed to °dONLNdä"◊.˛)^simplify°dONLNdì.<:(VZ,use of AppleTalk from high-level languages. °dONLNdø.:˛)‹.Instead, they’ve caused us a few compatibility°dONLNdÓ:<Få(bZ?problems. We’ve decided to encourage use of the same interface °dONLNd-:åF˛(b™that assembly-language°dONLNdDF<R(nZ/AppleTalk uses, a parameter-block interface in °dONLNdsFR˛)fi1the same style as the low-level interfaces to the°dONLNd•R<^∫(zZFile and Device Managers.°dONLNdøj<vi*DThe original calls are still supported (and will be for a while) as °dONLNdjiv˛(íá an “alternate” interface, but we°dONLNd$v<Ç (ûZNsuggest that you consider moving to the new “preferred” calls. Be warned that °dONLNdrv Ç˛(ûË
  5246. use of the°dONLNd}Ç<ém(™Z<original calls may cause compatibility problems with future °dONLNdπÇmé˛(™ãsystem software. Also, new°dONLNd‘é<ön(∂Z
  5247. protocols °dONLNdfiénö˛)2I(like ASP, the AppleTalk Session Protocol) are only provided with the new°dONLNd(ö<¶m(¬Z interfaces.°dONLNd4≤<æV*;The new interface uses parameter blocks like those used by °dONLNdo≤Væ˛(⁄t!the File and Device Managers; you°dONLNdëæ< #(ÊZ4fill out the call-specific fields of the block, and °dONLNd≈æ# ˛)Á*a small amount of glue code (provided with°dONLNdÀ<◊ç(ÛZBdevelopment environments like MPW) turns the parameter block into °dONLNd2Àç◊ó(Û´a °dONLNd4 ó÷»)
  5248. Control°dONLNd;À»◊˛)1  call to the°dONLNdH◊<„»(ˇZappropriate AppleTalk driver.°dONLNdfÔ<˚’*"Most calls have an interface like:
  5249. °dONLNdä`Ï+$BFUNCTION PSomeCall(thePBPtr: ATPPBptr; asyncFlag: BOOLEAN): OSErr;
  5250. °dONLNdÕ<+j(GZ    The glue °dONLNd÷j+¡).fills in the fields °dONLNdÍ¡*Î)WcsCode°dONLNdÎ+)* and °dONLNdı*>)ioRefNum°dONLNd˝>+˛)8( with the appropriate value for the call°dONLNd&+<7Ö(SZyou’re making.
  5251. °dONLNd5O<^1*'"Synchronous and Asynchronous calls
  5252. °dONLNdXj<vŸ*WYou can still make calls synchronously (“do it now”) or asynchronously (“start it now, °dONLNdØjŸv˛(혠   finish it°dONLNdπv<Ç≥(ûZsoon”). If you choose to °dONLNd“v≥Dz)wCmake a call asynchronously, be sure to provide a completion routine°dONLNdÉ<èa(´Zin the °dONLNdÇaéµ)% ioCompletion°dONLNd)ɵè)T> field (to be called when the call finally finishes), or poll °dONLNdgÉè˛(´the ¡X¡
  5253. (÷Z!NW 2 - AppleTalk Interface Update(÷1) of 2(ÏZM.NW.AppleTalkInterfaceUpdateˇ°¿Ù%%DSIDICT:_cv
  5254. currentdict /bu known {bu}if
  5255. userdict /_cv known not{userdict /_cv 30 dict put}if
  5256. _cv begin
  5257. /bdf{bind def}bind def
  5258. currentscreen/cs exch def/ca exch def/cf exch def
  5259. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5260. /ss{//cf //ca //cs setscreen}bdf
  5261. /stg{ss setgray}bdf
  5262. /strgb{ss setrgbcolor}bdf
  5263. /stcmyk{ss cvcmyk}bdf
  5264. /min1{dup 0 eq{pop 1}if}bdf
  5265. end
  5266. currentdict /bn known {bn}if
  5267. †øZ◊#ˇ ˇˇˇˇ#◊ 
  5268. IR,Times
  5269. .+6-Macintosh Technical Notes /4/˘,
  5270. Courier
  5271. °dONLNd)P*ioResult°dONLNdP*
  5272. )8+ field of the parameter block (the call is °dONLNd3
  5273. *0)∫done if °dONLNd;0)h)&ioResult°dONLNdCh*⁄)8 is less than or equal to°dONLNd]*6&(R60).°dONLNdaBNT*BYou must not move or dispose of a parameter block before the call °dONLNd£BTN⁄(jrfinishes; when the call does°dONLNd¿NZ)(v69complete, you are responsible for throwing the parameter °dONLNd˘N)Z⁄(vG%block away (if you allocated it using°dONLNdZfù(Ç6Memory Manager routines).°dONLNd:r~±*#Note that the alternate interfaces °dONLNd]r±~⁄)ô:generated a network event on completion of an asynchronous°dONLNdò~ä(¶6*call; this service is not provided by the °dONLNd¬~ä⁄)ÿ.preferred interfaces, partly because of future°dONLNdÒäñè(≤6Hcompatibility problems. See M.NW.NoNetEvents for background information.
  5274. °dONLNd:ÆΩ≠*'Packed data structures
  5275. °dONLNdQ…’>*Several °dONLNdY…>’⁄)&Vof the data structures used by the new interfaces are packed; Pascal doesn’t deal well°dONLNd∞’·3(˝6with °dONLNdµ’3·⁄)Pthese structures. Special calls are provided for building LAP and DPP write-data°dONLNd·Ìh(    6Estructures, NBP names-table elements, and ATP buffer data structures.°dONLNdL˙"*,For example, when registering a name (using °dONLNdx˘"Ñ("@PRegisterName)°dONLNdÜ˙Ñ⁄)b, you’ll use a°dONLNdïÅ(/6NamesTableEntry°dONLNd§Å.)i' structure. This structure consists of °dONLNdÀ.⁄)≠"a few unpacked fields, followed by°dONLNdÓò(;6Uan entity-name: three strings (representing the object, type, and zone fields of the °dONLNdCò⁄(;∂ name) packed°dONLNdP ,í(H6together. You can call °dONLNdgí+—)z    NBPSetNTE°dONLNdp —,A)? to pack the strings °dONLNdÖ A,q)p    into the °dONLNdéq+⁄)0NamesTableEntry°dONLNdû-9|(U6structure. When you °dONLNd≤-|9÷)dremove the name (°dONLNd√,÷8#)Z PRemoveName°dONLNdŒ-#9⁄)M(), you’ll use the entity-name by itself;°dONLNd˜:FS(b6 you can use °dONLNd9SEß); NBPSetEntity°dONLNd:ßFÂ)T to pack it in.
  5276. °dONLNd^m∏(â6Zone Interface Protocol
  5277. °dONLNd7zÜQ* A function, °dONLNdCyQÖ¡)9GetBridgeAddress°dONLNdSz¡Ü⁄)p;, is provided to obtain the node ID of a bridge, for use in°dONLNdèÜíØ(Æ6VZIP transactions (zero is returned if no bridge is present on your network). You make °dONLNdÂÜØí⁄(ÆÕ    ZIP calls°dONLNdÔíû÷(∫6(using ATP requests, as described in the °dONLNdí÷û')æInside AppleTalk°dONLNd'í'ût)Q chapter on ZIP.°dONLNd8¬ŒÇ(Í6Further Reference: Ì4Ì˘°dONLNdKœ*€.+
  5278. •°dONLNdMœ<€Æ)The AppleTalk Manager°dONLNdc€*Á.(H•°dONLNde€<Áç)Inside AppleTalk°dONLNdu€çÁı)Q (for ZIP information)°dONLNdåÁ*Û.(H•°dONLNdéÁ<Ûß)M.NW.HL.AppleTalk°dONLNd†Û*ˇ.(H•°dONLNd¢Û<ˇ¢)M.NW.NoNetEvents ¡4¡˘
  5279. (÷62) of 2(÷k!NW 2 - AppleTalk Interface Update+M.NW.AppleTalkInterfaceUpdateˇ™◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  5280. /ZÅ#
  5281.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5282. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5283. .WIQkWIQk+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5284. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5285. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5286.     l+&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5287. BÄ(Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É°dWORD†ç
  5288. IR.°dONLNdo<ÇÆ(úZ)NW 3 - AppleTalk Phase 2 on the Macintosh
  5289. °dONLNd*Å<êä*
  5290. Networking°dONLNd5Å\ê˛(¨zM.NW.AppleTalkPhase2
  5291. °dONLNdJú<®t(ƒZ Revised by:°dONLNdVúÑ®Â)HSriram Subramanian°dONLNdiú¥®˛(ƒ“
  5292. December 1989°dONLNdw®<¥q(–Z Written by:°dONLNdɮѥ*)HPete Helme & Sriram Subramanian°dONLNd£®¡¥˛(–fl August 1989°dONLNdØ¿<ÃÎ(ËZZThis Technical Note discusses the new features and calls available with AppleTalk Phase 2.°dONLNd
  5293. Õ<Ÿ‡*
  5294. Changes since August 1989:°dONLNd$Õ‡Ÿ()§  Incorporated °dONLNd3Õ(Ÿ;)Hthe ,
  5295. Courier°dONLNd7Ã;ÿz)    ClosePrep°dONLNd@ÕzŸï)? and °dONLNdEÃïÿ˛)CancelClosePrep°dONLNdUŸ<ÂD(Z9transitions and the new control calls to the .MPP driver. X°dONLNdè˛<
  5296. Ì*%$AppleTalk Phase 2 is only available °dONLNd≥˛Ì
  5297. ˛)±6on Macintosh Plus or later Macintosh platforms, and it°dONLNdÍ
  5298. <ˇ(2Z,requires the installation of AppleTalk file °dONLNd
  5299. ˇ˛)√2V53, or greater.  Both EtherTalk 2.0 and TokenTalk°dONLNdI<"(>Z/2.0 automatically install this AppleTalk file. °dONLNdx"˛)›+ Developer Technical Support can supply the°dONLNd§"<.œ(JZQPhase 2 drivers for development use; however, if you need to include the Phase 2 °dONLNdı"œ.˛(JÌ
  5300. drivers in°dONLNd.<:˝(VZ\your product, you must license them from Software Licensing.  For more information, contact:°dONLNd`F®R#+lApple Software Licensing°dONLNd|R®^* Apple Computer, Inc.,°dONLNdï^®jF* 20525 Mariani Avenue, M/S 38-I°dONLNd∑j®v* Cupertino, CA, 95014°dONLNdœv®ÇÛ* (408) 974-4667°dONLNd·Ç®é** AppleLink:  SW.LICENSE
  5301. °dONLNd¯¶<µˆ(—ZWhat is AppleTalk Phase 2?
  5302. °dONLNd¡<ÕQ*7AppleTalk Phase 2 contains enhancements to the routing °dONLNdJ¡QÕ˛(Èo!and naming services of AppleTalk.°dONLNdmÕ<Ÿ—(ıZAmong these enhancements is °dONLNdâÕ—Ÿ˛)ï;the ability to create AppleTalk networks which support more°dONLNd≈Ÿ<Â>(Z5than 254 nodes, and to do so in a manner that is, to °dONLNd˙Ÿ>²(\(the greatest extent possible, compatible°dONLNd#Â<Ò¨(
  5303. ZMwith current AppleTalk implementations and applications.  Multiple zones per °dONLNdpÂ¨Ò˛(
  5304.  network are now°dONLNdÄÒ<˝π(Zsupported, and users can °dONLNdôÒπ˝˛)}?choose their machine’s zone.  Benefits include improved network°dONLNdŸ˝<    Ø(%Ztraffic and better router °dONLNdÛ˝Ø    ˛)sBselection.  New calls and features have been implemented with this°dONLNd6    <(1Z,enhancement and are documented in this Note.
  5305. °dONLNdc-<<K*'&Are AppleTalk Phase 2 Drivers Present?
  5306. °dONLNdäH<Tó*JSo you want to use these new calls and features, but can you?  First, one °dONLNd‘HóT˛(pµneeds to check to see°dONLNdÍT<`K(|Z9if the node is running AppleTalk Phase 2.  There are two °dONLNd#TK`˛(|i#ways this can be accomplished.  The°dONLNdGa<m∞(âZeasiest way is to make a °dONLNd``∞l)t _SysEnvirons°dONLNdlamá)T call and check the returned °dONLNdâ`ál‚)É
  5307. atDrvrVersNum°dONLNdña‚mÂ)[ °dONLNdóaÂm˛)field.°dONLNdüm<y†(ïZIf this byte is greater °dONLNd∑m†y˛)dIthan or equal to 53, then AppleTalk Phase 2 drivers are present.  If, for°dONLNdz<ÜÜ(¢Zsome reason, a °dONLNdyÜÖ·)J
  5308. _SysEnvirons °dONLNdz·Üã)['call is not practical or otherwise not °dONLNdDzãܲ)™possible, one can check°dONLNd\Ü<ía(ÆZ7 bytes °dONLNddÜaí˛)%Woff the device control entry for the .MPP driver for a single byte, which is the driver ¡X¡
  5309. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷ˇ1) of 15(ÏZM.NW.AppleTalkPhase2ˇ°¿Ù%%DSIDICT:_cv
  5310. currentdict /bu known {bu}if
  5311. userdict /_cv known not{userdict /_cv 30 dict put}if
  5312. _cv begin
  5313. /bdf{bind def}bind def
  5314. currentscreen/cs exch def/ca exch def/cf exch def
  5315. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5316. /ss{//cf //ca //cs setscreen}bdf
  5317. /stg{ss setgray}bdf
  5318. /strgb{ss setrgbcolor}bdf
  5319. /stcmyk{ss cvcmyk}bdf
  5320. /min1{dup 0 eq{pop 1}if}bdf
  5321. end
  5322. currentdict /bn known {bn}if
  5323. †ø.◊#ˇ ˇˇˇˇ#◊ 
  5324. IR,Times
  5325. .+6-Macintosh Technical Notes /4/˘
  5326. °dONLNd*ƒ*&version (actually the low byte of the ,
  5327. Courier°dONLNd&ƒ)Ó)¨qFlags°dONLNd,Ó*Ò)* °dONLNd-Ò*)    field of °dONLNd6)P)'DCtlQHdr°dONLNd>P*⁄)8 in the DCE).  Again, if this°dONLNd\*6I(R6 byte is 53 °dONLNdg*I6⁄)1Uor greater, AppleTalk Phase 2 is present, and the calls and features outlined in this°dONLNdΩ6Bq(^6Note may be used.
  5328. °dONLNdœZiø*'Calls to the .MPP Driver
  5329. °dONLNdËuÅç*IAppleTalk Phase 2 introduces many new variables, and we highly recommend °dONLNd1uçÅ⁄(ù´that you use the°dONLNdBÇé/(™6new °dONLNdFÅ/çü)GetAppleTalkInfo°dONLNdVÇüé)p call instead of looking at °dONLNdrÇé⁄)y(MPP globals directly.  In addition, on a°dONLNdõéö3(∂6:Macintosh running the AppleTalk Internet Router software, °dONLNd’é3ö⁄(∂Qthere may be more than one .MPP°dONLNdıö¶i(¬6driver present.  °dONLNdöi¶⁄)QGThese additional drivers can be found by walking through the unit table°dONLNdNß≥(œ6(°dONLNdO¶≤b)
  5330. UTableBase°dONLNdYßb≥h)F °dONLNdZßh≥⁄)C$11C) and looking for drivers named .MPP other than at unit slot 9.°dONLNdü¥¿^(‹6Generally, the °dONLNdÆ¥^¿¶)FIonly port of interest to you is the user port, reflected in this call as °dONLNd˜≥¶ø–(‹ƒPortID°dONLNd˝¥–¿⁄)* 0°dONLNd¡Õ8(È6with a °dONLNd¿8Ãb) refnum°dONLNd
  5331. ¡bÕÜ)* of -10.°dONLNdŸÂ~(6GetAppleTalkInfo
  5332.     °dONLNd'Ò¸c*Parameter Block°dONLNd8˚*H+
  5333. --> 26°dONLNd?˚`~)6csCode°dONLNdF˚∫Œ)Zword°dONLNdK˚ã)6; always GetAppleTalkInfo (258)°dONLNdl*H(,H--> 28°dONLNds`É)6Version°dONLNd{∫Œ)Zword°dONLNdÄh)6; requested info version°dONLNdö*H(6H<-- 30°dONLNd°`É)6VarsPtr°dONLNd©∫›)Zpointer°dONLNd±ê)6 ; pointer to well known MPP vars°dONLNd”*$H(@H<-- 34°dONLNd⁄`$~)6DCEPtr°dONLNd·∫$›)Zpointer°dONLNdÈ$T)6; pointer to MPP DCE°dONLNdˇ#*.H(JH<-- 38°dONLNd#`.~)6PortID°dONLNd
  5334. #∫.Œ)Zword°dONLNd#.T)6; port number [0..7]°dONLNd(-*8H(TH<-- 40°dONLNd/-`8°)6
  5335. Configuration°dONLNd=-∫8Œ)Zlong°dONLNdB-8w)6 32-bit configuration word°dONLNd_7*BH(^H<-- 44°dONLNdf7`Bà)6SelfSend°dONLNdo7∫BŒ)Zword°dONLNdt7BÜ)6; non zero if SelfSend enabled°dONLNdîA*LH(hH<-- 46°dONLNdõA`Ly)6NetLo°dONLNd°A∫LŒ)Zword°dONLNd¶AL|)6; low value of network range°dONLNdƒK*VH(rH<-- 48°dONLNdÀK`Vy)6NetHi°dONLNd—K∫VŒ)Zword°dONLNd÷KVÅ)6; high value of network range°dONLNdıU*`H(|H<-- 50°dONLNd¸U``É)6OurAddr°dONLNdU∫`Œ)Zlong°dONLNd    U`Ü)6; our 24-bit AppleTalk address°dONLNd)_*jH(ÜH<-- 54°dONLNd0_`jí)6
  5336. RouterAddr°dONLNd;_∫jŒ)Zlong°dONLNd@_jï)6!; 24-bit address of (last) router°dONLNdci*tH(êH<-- 58°dONLNdji`tà)6NumOfPHs°dONLNdsi∫tŒ)Zword°dONLNdxitö)6"; max. number of protocol handlers°dONLNdús*~H(öH<-- 60°dONLNd£s`~ç)6    NumOfSkts°dONLNd≠s∫~Œ)Zword°dONLNd≤s~ã)6; max. number of static sockets°dONLNd”}*àH(§H<-- 62°dONLNd⁄}`àà)6NumNBPEs°dONLNd„}∫àŒ)Zword°dONLNdË}àÜ)6; max. concurrent NBP requests°dONLNdá*íH(ÆH<-- 64°dONLNdá`íÉ)6NTQueue°dONLNdá∫í›)Zpointer°dONLNdáíö)6"; pointer to registered name queue°dONLNdCë*úH(∏H<-> 68°dONLNdJë`úç)6    *LAlength°dONLNdTë∫úŒ)Zword°dONLNdYëúü)6#; length in bytes of data link addr°dONLNd~õ*¶H(¬H--> 70°dONLNdÖõ`¶ç)6    *LinkAddr°dONLNdèõ∫¶›)Zpointer°dONLNdóõ¶|)6; data link address returned°dONLNdµ•*∞H(ÃH--> 74°dONLNdº•`∞ç)6    *ZoneName°dONLNdΔ•∫∞›)Zpointer°dONLNdŒ•∞T)6; zone name returned°dONLNdÊØ`∫Ï(÷~* for extended networks only
  5337. °dONLNd≈—Ë(Ì6+This call is provided to simplify the task °dONLNd.≈Ë—⁄)–0of obtaining details about the current AppleTalk°dONLNd_—›à(˘6Nnetwork connection.  The following are the parameters which this call returns:°dONLNdÆÈıI*Version°dONLNd∂Íш9)l&is passed by the caller.  The concept °dONLNd‹Í9ˆ∂)µis similar to one used by°dONLNdˆˆÑÿ(¢ _SysEnvirons°dONLNd˜ÿfl)T, °dONLNd˜fl∂),where a version ID is passed to the function°dONLNd1ÑV(+¢-to return a requested level of information.  °dONLNd^V∂)“If the driver cannot°dONLNdsÑK(8¢#respond because this number is too °dONLNdñKm)«high, °dONLNdúm•)"paramErr°dONLNd§•∂)8 is°dONLNd®Ñ(P(D¢+returned.  The current version number is 1.°dONLNd‘(4I(Q6VarsPtr°dONLNd‹)Ñ5ê)lis °dONLNdfl)ê5∂) <the pointer to AppleTalk variables.  This points to the well°dONLNd    6ÑB™(^¢known °dONLNd    "5™A)&
  5338. sysLapAddr°dONLNd    ,6Bı)F °dONLNd    -6ıB∂)#and read header area or RHA..  This°dONLNd    QCÑO(k¢pointer may not be equal °dONLNd    jCO1)|    to $2D8 (°dONLNd    sB1Ni)1ABusVars°dONLNd    {CiO∂)8) for other than°dONLNd    åOÑ[§(w¢port 0.°dONLNd    î[gB(Ñ6DCEPtr°dONLNd    õ\Ñhm)l3is a pointer to the driver’s device control entry. °dONLNd    Œ\mh∂)ÈSee the Device°dONLNd    ›hÑtÁ(ê¢Manager chapters of °dONLNd    ÒhÁt8)cInside Macintosh°dONLNd
  5339. h8tn)Q
  5340.  for details.°dONLNd
  5341. tÄB(ù6PortID°dONLNd
  5342. uÑÅõ)l>is the port number, and it is always zero, unless a router is °dONLNd
  5343. TuõÅ∂(ùπactive°dONLNd
  5344. [ÇÑéø(™¢
  5345. and a driver °dONLNd
  5346. hÅøçÈ);refnum°dONLNd
  5347. nÇÈéV)* other than -10 is used. ¡4¡˘
  5348. (÷62) of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ‹◊#ˇ ˇˇˇˇ#◊ 
  5349. IR,Times
  5350. .+Z-Developer Support Center(-fi
  5351. December 1989 /X/,
  5352. Courier
  5353. °dONLNd<)ó(FZ
  5354. Configuration°dONLNd®*Ã)l9is a 32-bit word of configuration flags.  Currently only °dONLNdGÃ*⁄(FÍthe°dONLNdK*®6((RΔfollowing bits are returned:°dONLNdh7®Cª*
  5355. 31 (°dONLNdl6ªB˙)    SrvAdrBit°dONLNdu7˙C˛)?)    °dONLNdw7&C«),is true if server node-ID 
  5356. °dONLNdë7«C⁄)°was°dONLNdïC&Og(kD
  5357. requested at °dONLNd¢CgO⁄)Aopen time.  Note that°dONLNd∏O&[?(wDeven °dONLNdΩO?[⁄)"if server address is requested, it°dONLNd‡[&g∂(ÉDmay be ignored by those °dONLNd¯[∂g⁄)êADEVs
  5358. °dONLNd˛g&sÆ(èDwhich do not honor  °dONLNdgÆs⁄)à    it (i.e.,°dONLNds&Æ(õDEtherTalk, TokenTalk, etc.).°dONLNd8Ä®åª(®Δ30 (°dONLNd<ªã˙)    RouterBit°dONLNdEÄ˙å˛)?)°dONLNdGÄ&åí),is true if an AppleTalk °dONLNd_Äíå⁄)lInternet Router°dONLNdoå&ò√(¥Dwas loaded at system startup.  °dONLNdéå√ò⁄)ùNote°dONLNdìò&§;(¿Dthat °dONLNdòò;§⁄)a router may be loaded, but not°dONLNd∏§&∞E(ÃDactive.°dONLNd¿±®Ωµ(ŸΔ7 (°dONLNd√∞µº)
  5359. BadZoneHintBit°dONLNd—±Ω)b)°dONLNd”±&Ωa)is true if the °dONLNd‚±aΩ⁄);node’s zone name hint is°dONLNd˚Ω&…ì(ÂDinvalid, thus causing a °dONLNdΩì…⁄)mdefault zone to°dONLNd#…&’](ÒD be selected.°dONLNd0÷<‚I(˛Z6 (°dONLNd3’I·è)
  5360. OneZoneBit°dONLNd=÷è‚ì)F)°dONLNd?÷®‚¿)<is true if only one zone is assigned to an extended network.°dONLNd|‚<Ót( ZSelfSend°dONLNdÖ„®Ôê)l6(the ability for a node to send packets to itself) is °dONLNdª„êÔ⁄)Ënon-zero if this°dONLNdÃÔ®˚+(Δfeature is currently enabled.°dONLNdÍ˚<_($ZNetLo°dONLNd¸®Ÿ)l is the low °dONLNd˚¸Ÿ⁄)12value of the network range.  Non-extended networks°dONLNd.®Û(0Δalways have a °dONLNd<Û⁄)K,range of exactly one network, if the network°dONLNdi® ˇ(<Δnumber is known.°dONLNdz <,_(IZNetHi°dONLNdÄ!®-^)l'is the high value of the network range.°dONLNd®-<9m(VZOurAddr°dONLNd∞.®:)lis the 24-bit AppleTalk °dONLNd».:⁄)o&network address of the node.  The most°dONLNdÔ:®F:(bΔ significant byte is always zero.°dONLNdF<RÇ(oZ
  5361. RouterAddr°dONLNdG®S\)l'is the 24-bit AppleTalk address of the °dONLNdBG\S⁄)¥router from which we last°dONLNd\S®_—({Δ=heard.  Users should always use this address when attempting °dONLNdôS—_⁄({Ôto°dONLNdú_®kO(áΔ#communicate directly with a router.°dONLNd¿k<wt(îZNumOfPHs°dONLNd»ltxx)8,°dONLNd l®x4)4are maximum capacities for °dONLNdÂl4x⁄)åthe driver.  They are number of°dONLNdx®Ñœ(†Δprotocol°dONLNdÑ<ê{(≠Z    NumOfSkts°dONLNdÖ{ëì)?, and°dONLNdÖ®ë®)-2handlers, number of static sockets, and number of °dONLNdOÖ®ë⁄(≠Δ
  5362. concurrent°dONLNdZë®ù¿(πΔNBP°dONLNd^ù<©t(ΔZNumNBPEs°dONLNdgû®™:)lrequests allowed, respectively.°dONLNdá™<∂m(”ZNTQueue°dONLNdè´®∑)lis a pointer to the °dONLNd£´∑Ω)^#registered names table queue.  See °dONLNdΔ´Ω∑⁄)∑Inside°dONLNdÕ∑®√Ÿ(flΔ    Macintosh°dONLNd÷∑Ÿ√º)1+, Volume II, The AppleTalk Manager, for NT °dONLNd∑º√⁄)„Queue°dONLNd√®œ (ÎΔdetails.°dONLNdœ<€t(¯ZLALength°dONLNd–®‹ˆ)lis passed by the °dONLNd*–ˆ‹⁄)N0caller to indicate how much (if any) of the data°dONLNd[‹®ËÔ(Δlink address is °dONLNdk‹ÔË⁄)G1to be copied to a user-suppled buffer (pointed to°dONLNdùÈ®ı∑(Δby °dONLNd†Ë∑ÙÔ)LinkAddr°dONLNd®ÈÔı0)8).  The actual °dONLNd∑È0ı⁄)A%length is returned by the driver.  If°dONLNd›ı®π(Δthe °dONLNd·ıπ⁄)<caller requests more bytes than the actual number, then data°dONLNd®
  5363.     ()Δin the buffer after °dONLNd2    
  5364. ⁄)a(the address is undefined.  The caller is°dONLNd[
  5365. ®ê(5Δ2responsible for providing sufficient buffer space.°dONLNdé<%t(BZLinkAddr°dONLNdó®&»)l;is a pointer to a user-supplied buffer into which the data °dONLNd“»&⁄(BÊlink°dONLNd◊'®3d(OΔ+address data is copied.  If the pointer is °dONLNd&d2y)ºNIL°dONLNd'y3”), no data is copied.°dONLNd3<?t(\ZZoneName°dONLNd#4®@∫)l6is a pointer to a user-supplied buffer into which the °dONLNdY4∫@⁄(\ÿnode’s°dONLNd`A®M3(iΔstored zone name is copied. °dONLNd|A3Mã)ã If the pointer is °dONLNdè@ãL†)XNIL°dONLNdíA†M⁄) , no data is°dONLNdüM®Y∫(uΔ:copied.  The user buffer must be 33 bytes or more in size. ¡X¡
  5366. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷ˇ3) of 15(ÏZM.NW.AppleTalkPhase2ˇl◊#ˇ ˇˇˇˇ#◊ 
  5367. IR,Times
  5368. .+6-Macintosh Technical Notes /4/˘
  5369. °dONLNd)8æ*'Calls to the .ATP Driver
  5370. °dONLNdDPi*
  5371. KillAllGetReq,
  5372. Courier
  5373.     °dONLNd'\gc*Parameter Block°dONLNd7fqJ*
  5374.  
  5375.     --> 26°dONLNdBfrqê)ZcsCode°dONLNdIf∫qŒ)Hword°dONLNdNfÁqs)-; always KillAllGetReq (259)°dONLNdkp{J(ó6
  5376.     --> 28°dONLNdvpr{ü)Z    atpSocket°dONLNdÄp∫{Œ)Hbyte°dONLNdÖpÁ{†)-%; socket on which to kill all pending°dONLNdÆzÁÖ(*
  5377.  
  5378.   GetRequests
  5379. °dONLNdºêús(π6
  5380. KillAllGetReq°dONLNd…ësùö)[ aborts °dONLNd—ëöùË)'all outstanding °dONLNd·êËú.)N
  5381. GetRequest°dONLNdÎë.ù⁄)F" calls on the specified socket and°dONLNdû™|(Δ6completes them with °dONLNd"ù|©¬)d
  5382. reqAborted°dONLNd,û¬™⁄)F> errors (it does not close the specified socket, it only kills°dONLNdk´∑Q(”6 all pending °dONLNdw™Q∂ó)9
  5383. GetRequest°dONLNdÅ´ó∑)F calls on that socket). °dONLNdô´∑Q)l To kill all the °dONLNd™™Q∂ó)N
  5384. GetRequest°dONLNd¥´ó∑⁄)F calls, simply°dONLNd√∏ƒÀ(‡6&pass the desired socket number in the °dONLNdÈ∑À√
  5385. )≥    atpSocket°dONLNdÚ∏
  5386. ƒ&)? field.°dONLNd˙—›T(˘6 Result codes°dONLNd–`‹É)HnoErr°dONLNd—Û˜)lNo Error°dONLNd—§›≤)ÿ(0)°dONLNd!›`ȶ(~
  5387. cbNotFound°dONLNd,fiÃÍ;)lcontrol block not found°dONLNdFfi§Í»)ÿ(-1102)°dONLNdNˆ(6+Setting the TRel Timer in SendRequest Calls°dONLNdzs*It is now possible °dONLNdçsÌ)[to set the TRel timer in °dONLNd¶Ì:)z SendRequest°dONLNd±:N)M or °dONLNdµN´)
  5388. NSendRequest °dONLNd¬´⁄)]
  5389. calls with°dONLNdÕ'ä(C6ATP XO (exactly once) °dONLNd„ä'⁄)rEservice so as not to be locked into the pre-AppleTalk Phase 2 time of°dONLNd)(4î(P630 seconds.  This is done °dONLNdC(î4)|by setting bit 2 in the °dONLNd['38)latpFlags°dONLNdc(84⁄)8% field to indicate to the driver that°dONLNdâ5A(]61an extended parameter block is being used.  Make °dONLNd∫5A;)Ó a standard °dONLNd≈4;@à)5 SendRequest°dONLNd–5àA⁄)M call, but add the°dONLNd„BN¡(j6$timeout constant desired in the new °dONLNdA¡M˘)©TRelTime°dONLNdB˘N+)8  field byte °dONLNdB+N⁄)2#of the parameter block.  Both nodes°dONLNd?NZY(v6Cmust be running AppleTalk Phase 2 for this feature to be supported.°dONLNdÉgsv*KThe timeout constants are enumerated as follows in the lower three bits of °dONLNdŒgvsà(èîthe °dONLNd“fàr¿)TRelTime°dONLNd⁄g¿s⁄)8 ($32°dONLNd‡sQ(õ6
  5390. offset) byte:°dONLNdÔã<óN+$000°dONLNdÛã`ól)$$0°dONLNdˆãÑó
  5391. )$TRel timer set to 30 seconds°dONLNdó<£N(øZ001°dONLNdó`£l)$$1°dONLNdóÑ£    )$TRel timer set to one minute°dONLNd9£<ØN(ÀZ010°dONLNd=£`Øl)$$2°dONLNd@£ÑØ)$TRel timer set to two minutes°dONLNd_Ø<ªN(◊Z011°dONLNdcØ`ªl)$$3°dONLNdfØÑª)$TRel timer set to four minutes°dONLNdܪ<«N(„Z100°dONLNdäª`«l)$$4°dONLNdçªÑ«)$TRel timer set to eight minutes°dONLNd≠”fl¢(˚6All other values are reserved.
  5392.     °dONLNdÃΈc*Parameter Block°dONLNd‹ıJ*
  5393.  
  5394.     --> 50°dONLNdÁı`ç)H    TRelTime °dONLNdÒı®º)Hbyte°dONLNdˆıÃî)$(; indicates time to wait for TRel packet
  5395. °dONLNd&õ(B64Name Binding Protocol (NBP) Change:  Wildcard Lookup
  5396. °dONLNdT2>%*In °dONLNdW2%>⁄)
  5397. VAppleTalk Phase 2, NBP is enhanced to provide additional wildcard support.  The double°dONLNdÆ>J=(f6<tilde (≈), $C5, is now reserved in the object name and type °dONLNdÍ>=J⁄(f[strings and used in a lookup to°dONLNd
  5398. JV4(r6mean °dONLNdJ4V⁄)Ya match of zero or more characters.  Thus “≈cliff” matches “cliff,” ”the cliff,” ”grazing°dONLNdiVb\(~6off the cliff,” °dONLNdyV\b⁄)DHetc., and “123≈456” matches “123456,” “123zz456,” etc.  At most one ≈ is°dONLNd¬bnT(ä6=allowed in any string.  A single ≈ has the same meaning as a °dONLNdˇbTn⁄(ärsingle =, which also must°dONLNdnz§(ñ6continue to be accepted.  The °dONLNd7n§z⁄)å<≈ has no special meaning in zone names.  Clients of NBP must°dONLNdtzÜfl(¢6)be aware that “old” (pre-AppleTalk Phase °dONLNdùzflÜ⁄)«22) nodes may not process this new wildcard feature ¡4¡˘
  5399. (÷64) of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ–◊#ˇ ˇˇˇˇ#◊ 
  5400. IR,Times
  5401. .+Z-Developer Support Center(-fi
  5402. December 1989 /X/
  5403. °dONLNd<)((EZ1correctly.  This feature should probably only be °dONLNd1()˛)Ï)used when it is known that the responding°dONLNd[)<5 (QZ,devices are running Phase 2 drivers as well.
  5404. °dONLNdàM<\›*':Obtaining Zone Information Using the New .XPP Driver Calls
  5405. °dONLNd√h<t±*LPreviously, Zone Information Protocol (ZIP) functions were accomplished via °dONLNdh±t˛(êœdirect ATP calls°dONLNd u<År(ùZ
  5406. to the local °dONLNd-urŰ)6?router.  It was rather nasty business, having to mess with the ,
  5407. Courier°dONLNdlt°ÄÓ(ùø ATPUserData°dONLNdwuÓŞ)M on°dONLNd{Å<çµ(©ZOsubsequent calls to retain state information.  We now recommend the use of the °dONLNd Åµç˛(©”
  5408. following XPP°dONLNdÿç<ôÚ(µZ\driver calls to access ZIP.  Old ATP calls will continue to be supported for compatibility. °dONLNd4çÚô˛(µ It°dONLNd8ô<•ö(¡ZKshould also be noted that with Phase 2 drivers present, the .XPP driver is °dONLNdÉôö•˛(¡∏automatically opened°dONLNdò•<±g(ÕZby MPP.°dONLNd†Ω<…Ç* GetZoneList
  5409.     °dONLNd¨’<‡á*Parameter Block°dONLNdºfl<Ín*
  5410.  
  5411.     --> 26°dONLNd«flÑÍ¢)HcsCode°dONLNdŒfl’ÍÈ)Qword°dONLNd”flÍx)?; always xCall (246)°dONLNdËÈ<Ùn(Z
  5412.     --> 28°dONLNdÛÈÑÙ∂)H
  5413. xppSubCode°dONLNd˛È’ÙÈ)Qword°dONLNdÈÙõ)? always zipGetZoneList (6)°dONLNdÛ<˛n(Z
  5414.     --> 30°dONLNd*ÛÑ˛∂)H
  5415. xppTimeout°dONLNd5Û’˛È)Qbyte°dONLNd:Û˛ñ)?; retry interval (seconds)°dONLNdU˝<n($Z
  5416.     --> 31°dONLNd`˝Ñ¨)HxppRetry°dONLNdi˝’È)Qbyte°dONLNdn˝U)?
  5417. ; retry count°dONLNd|<n(.Z
  5418.         32°dONLNdáѨ)H<unused>°dONLNdê’È)Qword°dONLNdï“)?&; word space for rent.  see the super.°dONLNdº<n(8Z
  5419.     --> 34°dONLNd«Ñ∂)H
  5420. zipBuffPtr°dONLNd“’¯)Qpointer°dONLNd⁄◊)?'; pointer to buffer (must be 578 bytes)°dONLNd<&n(BZ
  5421.     <-- 38°dONLNd
  5422. Ñ&ª)H zipNumZones°dONLNd’&È)Qword°dONLNd&»)?$; no. of zone names in this response°dONLNdC%<0n(LZ
  5423.     <-- 40°dONLNdN%Ñ0ª)H zipLastFlag°dONLNdZ%’0È)Qbyte°dONLNd_%0õ)? non-zero if no more zones°dONLNd{/<:n(VZ
  5424.         41°dONLNdÜ/Ñ:¨)H<unused>°dONLNdè/’:È)Qbyte°dONLNdî/:<)?; filler°dONLNdù9<Dn(`Z
  5425.     --> 42°dONLNd®9ÑD¿)H ziplnfoField°dONLNdµ9’D˝)Q70 bytes°dONLNdæ9D·)?); on initial call, set first word to zero
  5426. °dONLNdÈO<[â(xZ GetZoneList°dONLNdÙPâ\é)M °dONLNdıPé\¨);is used to obtain a complete list of zones on the internet.°dONLNd0P¨\∏(x   °dONLNd2O∏[˛)
  5427. ZipBuffPtr°dONLNd=]<i”(ÖZ points to a buffer that.must be °dONLNd]]”i )ó 578 bytes (°dONLNdh\ hR)9
  5428. ATPMaxData°dONLNdr]Ri˛)F") in length.  The actual number of°dONLNdïj<v(íZ1zone names returned in the buffer is returned in °dONLNdΔiuk)‚ zipNumZones°dONLNd—jkv§)M
  5429. . The fields °dONLNdfii§uÍ)9
  5430. xppTimeout°dONLNdËjÍvÌ)F °dONLNdÈjÌv˛)and°dONLNdÌv<Çt(üZxppRetry°dONLNdıwtÉ≥)8E contain the ATP retry interval (in seconds) and count, respectively.°dONLNd;ê<ú=(∏Z8The first time this call is made, the first word of the °dONLNdsè=õë(∏[ ziplnfoField°dONLNdêëúÊ)T should be set to °dONLNdëêÊú˛)Uzero.°dONLNdòù<©µ(≈ZWhen the call completes, °dONLNd±úµ®)y zipLastFlag°dONLNdºù©)M °dONLNdΩù©˛)6is non-zero if all the zone names fit into the buffer.°dONLNdı™<∂æ(“ZIf not, the call should be °dONLNd™æ∂ö)Ç)made again immediately, without changing °dONLNd9©öµÓ)‹ zipInfoField°dONLNdE™Ó∂˛)T (it°dONLNdJ∂<¬∏(fiZcontains state information °dONLNde∂∏¬˛)|Fneeded to get the next part of the list).  The call should be repeated°dONLNd¨√<œT(ÎZuntil °dONLNd≤¬TŒ°) zipLastFlag°dONLNdΩ√°œ‡)M is non-zero. °dONLNdÀ√‡œ")?
  5431.  The 70-byte °dONLNdÿ¬"Œv)B zipInfoField°dONLNd‰√vœ˛)T must always be allocated at°dONLNdœ<€Œ(˜Zthe end of the parameter block.°dONLNd!Ë<Ùx* Result codes°dONLNd.ÁÑÛß)HnoErr°dONLNd5ËÙ)lNo Error°dONLNdBË»Ù÷)ÿ(0)°dONLNdHÙÑ—(¢ noBridgeErr°dONLNdTıU)lNo router is available°dONLNdnı»‡)ÿ(-93)°dONLNdvÑ
  5432. √(*¢    ReqFailed°dONLNdÅ≤)l(SendRequest failed; retry count exceeded°dONLNd™»Ï)ÿ(-1096)°dONLNd≤<'ı(CZ&Following are short examples of using °dONLNdÿı&B)π GetZoneList°dONLNd„B'F)M. ¡X¡
  5433. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷ˇ5) of 15(ÏZM.NW.AppleTalkPhase2ˇ J◊#ˇ ˇˇˇˇ#◊ 
  5434. IR,Times
  5435. .+6-Macintosh Technical Notes /4/˘
  5436. °dONLNd)5<*$Pascal,
  5437. Courier
  5438.     °dONLNdAL6* const°dONLNdKV—*
  5439. %{ csCodes for new .XPP driver calls }°dONLNd4U`^*
  5440.   xCall = 246;°dONLNdCitc*{ xppSubCodes }°dONLNdSs~ã*
  5441.   zipGetLocalZones = 5;°dONLNdk}àÅ*
  5442.   zipGetZoneList = 6;°dONLNdÅáíw*
  5443.   zipGetMyZone = 7;°dONLNdïõ¶1* type°dONLNdõ•∞—*
  5444. %{ offsets for xCall queue elements  }°dONLNd¡Ø∫©*
  5445.    xCallParam = packed record°dONLNdflπƒ|*
  5446.     qLink: QElemPtr;°dONLNdÙ√Œw*
  5447.     qType: INTEGER;°dONLNdÕÿ|*
  5448.     ioTrap: INTEGER;°dONLNd◊‚w*
  5449.     ioCmdAddr: Ptr;°dONLNd1·Ïö*
  5450.     ioCompletion: ProcPtr;°dONLNdLΈ|*
  5451.     ioResult: OsErr;°dONLNdaıï*
  5452.     ioNamePtr: StringPtr;°dONLNd{ˇ
  5453. ã*
  5454.     ioVRefNum: INTEGER;°dONLNdì    Ü*
  5455.     ioRefNum: INTEGER;°dONLNd™|*
  5456.     csCode: INTEGER;°dONLNdø(ê*
  5457.     xppSubCode: INTEGER;°dONLNdÿ'2Å*
  5458.     xppTimeOut: Byte;°dONLNdÓ1<w*
  5459.     xppRetry: Byte;°dONLNd;F|*
  5460.     filler: INTEGER;°dONLNdEP|*
  5461.     zipBuffPtr: Ptr;°dONLNd,OZï*
  5462.     zipNumZones: INTEGER;°dONLNdFYdï*
  5463.     zipLastFlag: INTEGER;°dONLNd`cn˛*
  5464. .    zipInfoField: packed array[1..70] of Byte;°dONLNdèmx;*
  5465.    end;°dONLNdóÅå§*procedure doGetZoneListPhs2;°dONLNd¥ï†,*type°dONLNdπü™≥*
  5466.    XCallParamPtr = ^XCallParam;°dONLNdŸ©¥'*
  5467. var°dONLNd›≥æÜ*
  5468.    xpb: XCallParamPtr;°dONLNdÙΩ»Å*
  5469.    resultCode: OSErr;°dONLNd
  5470. «“Ω*
  5471. !   zoneBuffer, theBufferPtr: Ptr;°dONLNd,—‹ã*
  5472.    totalZones: integer;°dONLNdD€Ê1*
  5473. begin°dONLNdJÂ*
  5474. 4   xpb := XCallParamPtr(NewPtr(sizeof(XCallParam)));°dONLNd˘¬*"   zoneBuffer := NewPtr(33 * 100);°dONLNd¢˘Ãq)¥!{ size of maxstring * 100 zones }°dONLNdƒ
  5475. ≥(46   theBufferPtr := NewPtr(578);°dONLNd‰
  5476. Ã:)¥{ size of atpMaxData }°dONLNd˚!,©(H6   xpb^.zipInfoField[1] := 0;°dONLNd!Ã,∑)¥/{ ALWAYS 0 on first call.  contains state info °dONLNdM+Ã6?*
  5477.   on subsequent calls }°dONLNde?J©(f6   xpb^.zipInfoField[2] := 0;°dONLNdÉ?ÃJ∑)¥/{ ALWAYS 0 on first call.  contains state info °dONLNd∑IÃT?*
  5478.   on subsequent calls }°dONLNdœ]hÆ(Ñ6   xpb^.ioRefNum := XPPRefNum;°dONLNdÔ]hY)ÿ{ driver refNum -41 } ¡4¡˘
  5479. (÷66) of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ
  5480. ú◊#ˇ ˇˇˇˇ#◊ 
  5481. IR,Times
  5482. .+Z-Developer Support Center(-fi
  5483. December 1989 /X/,
  5484. Courier
  5485.     °dONLNd'<2¥(NZ   xpb^.csCode := xCall;°dONLNd1<<ı*
  5486. %   xpb^.xppSubCode := zipGetZoneList;°dONLNd?;<F¥*
  5487.    xpb^.xppTimeOut := 3;°dONLNdXE<P™*
  5488.    xpb^.xppRetry := 4;°dONLNdoO<Z*
  5489. (   xpb^.zipBuffPtr := Ptr(theBufferPtr);°dONLNdòOZ√)ÿ#{ this buffer will be filled with }°dONLNd¬YdÇ*
  5490. (  packed zone names }°dONLNdŸm<x√(îZ{ initialization for loop }°dONLNdıw<Çπ*
  5491.    xpb^.zipLastFlag := 0;°dONLNdÅ<åõ*
  5492.    totalZones := 0;°dONLNd#ã<ñõ*
  5493.    resultCode := 0;°dONLNd7ü<™Y*9{ loop until zipLastFlag is non-zero or an error occurs }°dONLNdq©<¥Y*
  5494. 9   while ((xpb^.zipLastFlag = 0) and (resultCode = 0)) do°dONLNd´≥<æd*
  5495.    begin°dONLNd¥Ω<»;*
  5496. 3   resultCode := PBControl(ParmBlkPtr(xpb), false);°dONLNdË—<‹◊*   if (resultCode = noErr) then°dONLNd€<Ên*
  5497.  
  5498.      begin°dONLNdÂ<;*
  5499. 3       totalZones := xpb^.zipNumZones + totalZones;°dONLNdGÔ<˙r*
  5500. >       { you can now copy the zone names into the zoneBuffer }°dONLNdܢ<i*
  5501.          end;°dONLNdê<_*
  5502.    end;°dONLNdò
  5503. <√*
  5504.    DisposPtr(theBufferPtr);°dONLNd¥<"π*
  5505.    DisposPtr(zoneBuffer);°dONLNdŒ!<,Ø*
  5506.    DisposPtr(Ptr(xpb));°dONLNdÊ+<6P*
  5507. end;
  5508. °dONLNdÎA<ME*C
  5509.     °dONLNdÌY<dF*/*°dONLNdÒc<n·*
  5510. !csCodes for new .XPP driver calls°dONLNdm<xF*
  5511. */°dONLNdw<Ç}*
  5512.  
  5513. #define xCall°dONLNd&wÃÇ€)ê246°dONLNd*ã<ñF(≤Z/*°dONLNd.ï<†s*
  5514. xppSubCodes°dONLNd;ü<™F*
  5515. */°dONLNd>©<¥π*
  5516. #define zipGetLocalZones °dONLNdX©Ã¥—)ê5°dONLNdZ≥<æ™(⁄Z#define zipGetZoneList°dONLNdq≥Ãæ—)ê6°dONLNdsΩ<»•(‰Z#define zipGetMyZone °dONLNdâΩû—)ê7°dONLNdã—<‹F(¯Z/*°dONLNdê€<Ê‹*
  5517.  offsets for xCall queue elements°dONLNd≥Â<F*
  5518. */°dONLNd∂Ô<˙Ç*
  5519. typedef struct°dONLNd≈˘<U*
  5520.     {°dONLNdÀ<x*
  5521.     QElemPtr°dONLNd⁄ÃÍ)êqLink;°dONLNd·
  5522. <i(4Z        short°dONLNdÌ
  5523. ÃÍ)êqType;°dONLNdÙ<"i(>Z        short°dONLNdÃ"Ô)êioTrap;°dONLNd!<,_(HZ    Ptr°dONLNd!Ã,˛)ê
  5524. ioCmdAddr;°dONLNd+<6s(RZ     ProcPtr°dONLNd++Ã6
  5525. ioCompletion;°dONLNd95<@i(\Z        OsErr°dONLNdE5Ã@˘)ê    ioResult;°dONLNdO?<J}(fZ
  5526.     StringPtr°dONLNd_?ÃJ˛)ê
  5527. ioNamePtr;°dONLNdjI<Ti(pZ        short°dONLNdvIÃT˛)ê
  5528. ioVRefNum;°dONLNdÅS<^i(zZ        short°dONLNdçSÃ^˘)ê    ioRefNum;°dONLNdó]<hi(ÑZ        short°dONLNd£]ÃhÔ)êcsCode;°dONLNd´g<ri(éZ        short°dONLNd∑gÃr)ê xppSubCode;°dONLNd√q<|ë(òZ    unsigned char°dONLNd÷qÃ|)ê xppTimeOut;°dONLNd‚{<Üë(¢Z    unsigned char°dONLNdı{Ãܢ)ê    xppRetry;°dONLNdˇÖ<êi(¨Z        short°dONLNd ÖÃêÔ)êfiller; ¡X¡
  5529. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷ˇ7) of 15(ÏZM.NW.AppleTalkPhase2ˇÓ◊#ˇ ˇˇˇˇ#◊ 
  5530. IR,Times
  5531. .+6-Macintosh Technical Notes /4/˘,
  5532. Courier
  5533.     °dONLNd(;*    Ptr°dONLNd
  5534. ®(fl)ê zipBuffPtr;°dONLNd'2E(N6        short°dONLNd"'®2‰)ê zipNumZones;°dONLNd/1<E(X6        short°dONLNd;1®<‰)ê zipLastFlag;°dONLNdH;Fm(b6    unsigned char°dONLNd[;®F˝)êzipInfoField[70];°dONLNdmEPY(l6
  5535. } xCallParam;°dONLNd{Ydw*doGetZoneListPhs2()°dONLNdècn*
  5536. {°dONLNdëmx^*
  5537.     xCallParam°dONLNd°m®xº)êxpb;°dONLNd¶wÇE(û6        OSErr°dONLNd≤w®ÇÛ)êresultCode = 0;°dONLNd¬Åå;(®6    Ptr°dONLNdÃÅ®å%)êzoneBuffer, theBufferPtr;°dONLNdÊãñE(≤6        short°dONLNdÚã®ñÛ)êtotalZones = 0;°dONLNdü™∏(Δ6     zoneBuffer = NewPtr(33*100);°dONLNd$ü™ü)ÿ#/* size of maxstring * 100 zones */°dONLNdH≥æ≥(⁄6    theBufferPtr = NewPtr(578);°dONLNdi≥æh)ÿ/* size of atpMaxData */°dONLNdÇ«“§(Ó6    xpb.zipInfoField[0] = 0;°dONLNd†«“©)ÿ%/* ALWAYS 0 on first call.  contains °dONLNdÀ—‹§*
  5538. $   state info on subsequent calls */°dONLNd€ʧ(6    xpb.zipInfoField[1] = 0;°dONLNd€Ê©)ÿ%/* ALWAYS 0 on first call.  contains °dONLNd9Â§*
  5539. $   state info on subsequent calls */°dONLNd^˘Ω( 6!    /* initialization for loop */°dONLNdÄê*
  5540.     xpb.zipLastFlag = 0;°dONLNdô"Æ*    xpb.ioCRefNum = XPPRefNum;°dONLNdπ"c)ÿ/* driver refNum -41 */°dONLNd—!,ã(H6    xpb.csCode = xCall;°dONLNdÈ+6Ã*
  5541. $    xpb.xppSubCode = zipGetZoneList;°dONLNd5@ã*
  5542.     xpb.xppTimeOut = 3;°dONLNd&?JÅ*
  5543.     xpb.xppRetry = 4;°dONLNd<IT‡*
  5544. (    xpb.zipBuffPtr = (Ptr) theBufferPtr;°dONLNdeITö)ÿ"/* this buffer will be filled with°dONLNdéS^h*
  5545. the packed zone names */°dONLNd®g<rc(éZ;/* loop until zipLastFlag is non-zero or an error occurs */°dONLNdÂq<|,*
  5546. 0while(xpb.zipLastFlag == 0 && resultCode == 0) {°dONLNdÖ<ê*(    resultCode = PBControl(&xpb, false);°dONLNdAô<§Õ*    if(resultCode == noErr) {°dONLNda£`Æ
  5547. +$
  5548. "    totalZones += xpb.zipNumZones;°dONLNdÜ≠`∏ë*
  5549. =    /* you can now copy the zone names into the zoneBuffer */°dONLNdΔ∑`¬e*
  5550. }°dONLNd»¡ç(Ë6    DisposPtr(theBufferPtr);°dONLNdÂÀ÷ö*
  5551.     DisposPtr(zoneBuffer);°dONLNd’‡1*
  5552.     }°dONLNdflÍ*
  5553. }
  5554. °dONLNdım*
  5555. GetLocalZones
  5556.     °dONLNd
  5557. c*Parameter Block°dONLNd&"J*
  5558.  
  5559.     --> 26°dONLNd1`"~)HcsCode°dONLNd8±"≈)Qword°dONLNd="T)?; always xCall (246)°dONLNdR!,J(H6
  5560.     --> 28°dONLNd]!`,í)H
  5561. xppSubCode°dONLNdh!±,≈)Qword°dONLNdm!,Å)?; always zipGetLocalZones (5)°dONLNdã+6J(R6
  5562.     --> 30°dONLNdñ+`6í)H
  5563. xppTimeout°dONLNd°+±6≈)Qbyte°dONLNd¶+6r)?; retry interval (seconds)°dONLNd¡5@J(\6
  5564.     --> 31°dONLNdÃ5`@à)HxppRetry°dONLNd’5±@≈)Qbyte°dONLNd⁄5@1)?
  5565. ; retry count°dONLNdË?JJ(f6
  5566.         32°dONLNdÛ?`Jà)H<unused>°dONLNd¸?±J≈)Qword°dONLNd?J)?; filler°dONLNd
  5567. ITJ(p6
  5568.     --> 34°dONLNdI`Tí)H
  5569. zipBuffPtr°dONLNd I±T‘)Qpointer°dONLNd(IT≥)?'; pointer to buffer (must be 578 bytes)°dONLNdPS^J(z6
  5570.     <-- 38°dONLNd[S`^ó)H zipNumZones°dONLNdgS±^≈)Qword°dONLNdlS^§)?$; no. of zone names in this response°dONLNdë]hJ(Ñ6
  5571.     <-- 40°dONLNdú]`hó)H zipLastFlag°dONLNd®]±h≈)Qbyte°dONLNd≠]hw)? non-zero if no more zones°dONLNd…grJ(é6
  5572.         41°dONLNd‘g`rà)H<unused>°dONLNd›g±r≈)Qbyte°dONLNd‚gr)?; filler°dONLNdÎq|J(ò6
  5573.     --> 42°dONLNdˆq`|ú)H ziplnfoField°dONLNdq±|Ÿ)Q70 bytes°dONLNd q|Ω)?); on initial call, set first word to zero°dONLNd9{Ü©*
  5574. %; on subsequent calls, do not modify! ¡4¡˘
  5575. (÷68) of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ.◊#ˇ ˇˇˇˇ#◊ 
  5576. IR,Times
  5577. .+Z-Developer Support Center(-fi
  5578. December 1989 /X/
  5579. °dONLNd<*U(FZThis °dONLNdU*1)+call has the same format and procedures as ,
  5580. Courier°dONLNd01)~)‹ GetZoneList°dONLNd;~*˛)M, the difference being that°dONLNdW*<6ó(SZ
  5581. GetLocalZones°dONLNdd+ó7æ)[     returns °dONLNdm+æ7˛)'Aa list of zone names currently defined only on the node’s network°dONLNdØ8<D'(`Z3cable rather than the entire network.  The 70-byte °dONLNd‚7'C{)Î zipInfoField°dONLNdÓ8{Dˆ)T must always be allocated °dONLNd8ˆD˛){at°dONLNd D<PŒ(lZthe end of the parameter block.°dONLNd+]<ix* Result codes°dONLNd8\Ñhß)HnoErr°dONLNd?]i)lNo Error°dONLNdL]»i÷)ÿ(0)°dONLNdRiÑu—(í¢ noBridgeErr°dONLNd^jvU)lNo router is available°dONLNdxj»v‡)ÿ(-93)°dONLNdÄvÑÇ√(ü¢    ReqFailed°dONLNdãwÉ≤)l(SendRequest failed; retry count exceeded°dONLNd¥w»ÉÏ)ÿ(-1096)°dONLNdºê<ú[(∏ZNote:°dONLNd¬ê`úµ)$The examples for °dONLNd”èµõ)U GetZoneList°dONLNdfiêúL)M will also work °dONLNdÓêLú^)Jfor °dONLNdÚè^õπ)
  5582. GetLocalZones°dONLNdˇêπú⁄)[ if you°dONLNdù`©°(≈~substitute the °dONLNdú°®Á)A
  5583. xppSubCode°dONLNd ùÁ©Î)F.°dONLNd"µ<¡~(›Z    GetMyZone
  5584.     °dONLNd,Õ<ÿá*Parameter Block°dONLNd<◊<‚n*
  5585.  
  5586.     --> 26°dONLNdG◊{‚û)?csCode °dONLNdO◊«‚€)Lword°dONLNdT◊‚f);; always xCall (246)°dONLNdi·<Ïn(Z
  5587.     --> 28°dONLNdt·{Ï≤)? xppSubCode °dONLNdÄ·«Ï€)Lword°dONLNdÖ·Ï);; always zipGetMyZone (7)°dONLNdüÎ<ˆn(Z
  5588.     --> 34°dONLNd™Î{ˆ≤)? zipBuffPtr °dONLNd∂ΫˆÍ)Lpointer°dONLNdæÎˆ¿);&; pointer to buffer (must be 33 bytes)°dONLNdÂı<n(Z
  5589.     --> 42°dONLNdı{º)?
  5590. ziplnfoField °dONLNd˛ı«Ô)L70 bytes°dONLNdıË);.; first word must be set to zero on every call
  5591. °dONLNd6 <{(4Z    GetMyZone°dONLNd? {s)?2 returns the node’s AppleTalk zone name.  This is °dONLNdq s˛)¯the zone in which all of the°dONLNdé<%(AZ1node’s network visible entities are registered.  °dONLNdø$^)‹
  5592. ZipBuffPtr°dONLNd…^%„)F points to a buffer that must °dONLNdÁ„%˛)Öbe 33°dONLNdÌ&<2õ(NZbytes in length.  If °dONLNd%õ1Ë)_ noBridgeErr°dONLNd
  5593. &Ë2ø)M0 is returned by the call, there is no internet, °dONLNd=&ø2˛)◊ and the zone°dONLNdJ3<?‰([Z&name is effectively an asterisk (*).  °dONLNdp3‰?")® The 70-byte °dONLNd|2">v)> zipInfoField°dONLNdà3v?˛)T must always be allocated at°dONLNd•?<KŒ(gZthe end of the parameter block.°dONLNd≈X<dx* Result codes°dONLNd“WÑcß)HnoErr°dONLNdŸXd)lNo Error°dONLNdÊX»d÷)ÿ(0)°dONLNdÏdÑp—(ç¢ noBridgeErr°dONLNd¯eqU)lNo router is available°dONLNde»q‡)ÿ(-93)°dONLNdqÑ}√(ö¢    ReqFailed°dONLNd%r~≤)l(SendRequest failed; retry count exceeded°dONLNdNr»~Ï)ÿ(-1096)°dONLNdVã<óı(≥Z&Following are short examples of using °dONLNd|äıñ4)π    GetMyZone°dONLNdÖã4ó8)?.°dONLNdá£<Ø`(ÀZPascal
  5594.     °dONLNdéª<Δ¥*procedure getMyZonePhs2;°dONLNdß≈<–K*
  5595. var°dONLNd´œ<⁄ñ*
  5596.    xpb:xCallParam;°dONLNdæŸ<‰•*
  5597.    resultCode :OSErr;°dONLNd‘„<Ó¥*
  5598.    myZoneNameBuffer:Ptr;°dONLNdÌÌ<¯U*
  5599. begin°dONLNdÛ˜<Î*
  5600. #   myZoneNameBuffer  := NewPtr(33);°dONLNd <“*   xpb.ioCRefNum := xppRefNum;°dONLNd6< Ø*
  5601.    xpb.csCode := xCall;°dONLNdN<*Ê*
  5602. "   xpb.xppSubCode := zipGetMyZone;°dONLNdq)<4˙*
  5603. &   xpb.zipBuffPtr := myZoneNameBuffer;°dONLNdò3<>»*
  5604.    xpb.zipInfoField[1] := 0;°dONLNd∂3>P)ÿ { ALWAYS 0 }°dONLNd√=<H»(dZ   xpb.zipInfoField[2] := 0;°dONLNd·=HP)ÿ { ALWAYS 0 }°dONLNdÓG<R(nZ(   resultCode := PBControl(@xpb, false);°dONLNdQ<\P*
  5605. end; ¡X¡
  5606. *^)NW 3 - AppleTalk Phase 2 on the Macintosh(÷ˇ9) of 15(ÏZM.NW.AppleTalkPhase2ˇñ◊#ˇ ˇˇˇˇ#◊ 
  5607. IR,Times
  5608. .+6-Macintosh Technical Notes /4/˘
  5609. °dONLNd)5!*$C,
  5610. Courier
  5611.     °dONLNdALc*getMyZonePhs2()°dONLNdKV*
  5612. {°dONLNdU`^*
  5613.     xCallParam°dONLNd#UÑ`ò)lxpb;°dONLNd(_jE(Ü6        OSErr°dONLNd3_Ñjª)l resultCode;°dONLNd?it;(ê6    Ptr°dONLNdHiÑtŸ)lmyZoneNameBuffer;°dONLNdZ}àÃ(§6$    myZoneNameBuffer  := NewPtr(33);°dONLNdëúÆ*    xpb.ioCRefNum = xppRefNum;°dONLNdûõ¶ã*
  5614.     xpb.csCode = xCall;°dONLNd∂•∞¬*
  5615. "    xpb.xppSubCode = zipGetMyZone;°dONLNdŸØ∫Ù*
  5616. ,    xpb.zipBuffPtr = (Ptr) myZoneNameBuffer;°dONLNdπƒ§*
  5617.     xpb.zipInfoField[0] = 0;°dONLNd$πƒ6)ÿ/* ALWAYS 0 */°dONLNd3√Œ§(Í6    xpb.zipInfoField[1] = 0;°dONLNdQ√Œ6)ÿ/* ALWAYS 0 */°dONLNd`Õÿ‡(Ù6(    resultCode = PBControl(&xpb, false);°dONLNdâ◊‚*
  5618. }
  5619. °dONLNdãÌ˘Ö*Potential Nastiness°dONLNdü8*8When running on a node with Phase 2 compatible drivers, °dONLNd◊8⁄(-Vwe always recommend using the°dONLNdıA(96=.XPP calls outlined in the previous section.  Care was taken °dONLNd2A⁄(9_to keep backward compatibility°dONLNdQ)ß(E6with the already existing ATP °dONLNdoß)⁄)è@ZIP calls (they are being trapped out with the Phase 2 drivers),°dONLNd∞)5'(Q67but there are problems about which you should be aware.°dONLNdËA*M.+•°dONLNdÍA7Mo)
  5620. Do not rely °dONLNdˆAoM∂)8Fon checking the TID (transaction ID validity bit) or other bits in the°dONLNd=M7Yo(vUatpFlags°dONLNdENoZâ)8, as °dONLNdJNâZS)"some of you have been doing.  The °dONLNdlMSYã) atpFlags°dONLNdtNãZ∂)8 are not°dONLNd}Z7fï(ÇUJguaranteed to be correct on an ATP ZIP call with a Phase 2 driver present.°dONLNd»g*s.(èH•°dONLNd g7s‹)
  5621. #Do not repeatedly stuff the router °dONLNdÌg‹sJ)•address back into the °dONLNdfJr•)n
  5622. ATPParamBlock°dONLNdg•s∂)[ on°dONLNdt7Ķ(úUsubsequent ATP ZIP °dONLNd's¶Û)o GetZoneList°dONLNd2tÛÄt)M calls.  There exists the °dONLNdLttÄ∂)Åpossibility of°dONLNd[Å7çm(©U concurrent °dONLNdfÄmå∫)6 GetZoneList°dONLNdqÅ∫çæ)M °dONLNdrÅæç∂)0calls being made by other tasks and wrong router°dONLNd£ç7ô√(µUaddresses being used (a small
  5623. °dONLNd¿ç√ôΔ)å 
  5624. °dONLNd¡çΔôc)$possibility yes, but it does exist).
  5625. °dONLNdʱ¿Û(‹6The AppleTalk Transition Queue
  5626. °dONLNdÃÿC*To keep °dONLNd
  5627. ÃCÿ⁄)+Papplications and other resident processes on the Macintosh informed of AppleTalk°dONLNd^ÿ‰?(6>events, such as the opening and closing of AppleTalk drivers, °dONLNdúÿ?‰⁄(]a new transition queue has been°dONLNdº‰`( 6implemented.  °dONLNd ‰`⁄)HJProcesses can register themselves with the AppleTalk Transition Queue, and°dONLNd¸˝(6.when a significant event occurs, they will be °dONLNdC˝¸⁄)Â-notified of this fact.  Each transition queue°dONLNdq¸2($67element has the following MPW assembly-language format:
  5628.     °dONLNd©@*AeQentry°dONLNd≤`~)HRECORD°dONLNd∫®≠)H0°dONLNdº)1(E6QLink°dONLNd√`)t)HDS.L°dONLNd…®)≠)H1°dONLNdÀÃ)5)$; link to next record°dONLNd·(31(O6QType°dONLNdË(`3t)HDS.W°dONLNdÓ(®3≠)H1°dONLNd(Ã3Ù)$; unused°dONLNd˘2=@(Y6CallAddr°dONLNd2`=t)HDS.L°dONLNd2®=≠)H1°dONLNd
  5629. 2Ã=D)$; pointer to task record°dONLNd%<`Gt(c~ENDR
  5630. °dONLNd*R^ø(z6"Three calls have been provided in °dONLNdLRø^⁄)ß5the LAP Manager to add an entry, remove an entry, and°dONLNdÇ^jS(Ü6Breturn a pointer to the AppleTalk event queue header.  The method °dONLNdƒ^Sj⁄(Üqfor making calls to the LAP°dONLNd‡jv¯(í60Manager is explained in the following section.  °dONLNdj¯v⁄)‡+The queue is maintained by the LAP Manager,°dONLNd<vÇ(û65so it can be active even when AppleTalk (MPP) is not. ¡4¡˘
  5631. *810)
  5632.  of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ¢◊#ˇ ˇˇˇˇ#◊ 
  5633. IR,Times
  5634. .+Z-Developer Support Center(-fi
  5635. December 1989 /X/
  5636. °dONLNd<)‹(EZMaking a LAP Manager Call°dONLNd5<A†*LThe LAP Manager is installed in the system heap at startup time, before the °dONLNdf5†A˛(]æAppleTalk Manager°dONLNdxA<MË(iZQopens the .MPP driver (hence, the inclusion of the AppleTalk Transition Queue in °dONLNd…AËM˛(iLAP°dONLNdÕM<Y(uZ(Manager rather than under .MPP).  Calls °dONLNdıMY˛)ƒ0are made to the LAP Manager by jumping through a°dONLNd&Z<fÍ(ÇZ#low-memory location, with register ,
  5637. Courier°dONLNdIYÍe¯)ÆD0°dONLNdKZ¯f˛)7 equal to a dispatch code that identifies the function.°dONLNdÑf<r•(éZThe exact sequence is:
  5638.     °dONLNdõ~<â©*I              MOVEQ     #Code,D0        ; D0 = ID code of wanted LAP call°dONLNdÂà<ìÃ*
  5639. P              MOVE.L    LAPMgrPtr,An    ; An -> start of LAP manager (from $B18)°dONLNd6í<ùΩ*
  5640. M              JSR       LAPMgrCall(An)  ; Call the LAP manager at entry point°dONLNdѶ<±§*HLAPMgrPtr     EQU       $B18            ; This points to our start (more°dONLNdÕ∞<ªï*
  5641. E                                        ; commonly known as ATalkHk2)°dONLNd∫<≈Æ*
  5642. JLAPMgrCall    EQU       2               ; Offset to make LAP manager calls
  5643. °dONLNd^–<‹2*(The AppleTalk Transition Queue LAP Calls°dONLNdáÈ<ıu*LAddAEQ°dONLNdéÈuı|)9 (°dONLNdêË|Ùä)D0°dONLNdíÈäı°)=23)°dONLNdóˆ<R(ZCall:°dONLNdûıÑß)HA0-->°dONLNd•ˆ”)l/Entry to be added to the AppleTalk event queue.°dONLNd’<Q(7ZThe °dONLNdŸQÇ)LAddAEQ°dONLNd‡Ç)1# call adds an entry, pointed to by °dONLNd-)ùA0°dONLNd-¡), to the AppleTalk event queue.
  5644.     °dONLNd&'{2î(NôMOVEQ°dONLNd,'®2fl)- #LAddAEQ,D0°dONLNd8'2∞)^"; D0 = 23 code of LAddAEQ LAP call°dONLNd\1{<ô(XôMOVE.L°dONLNdc1®<‰)- LAPMgrPtr,An°dONLNdp1<Œ)^(; An -> start of LAP manager (from $B18)°dONLNdö;{Fä(bôJSR°dONLNdû;®FÓ)-LAPMgrCall(An)°dONLNd≠;Fø)^%; Call the LAP manager at entry point
  5645. °dONLNd”R<^x(zZLRmvAEQ°dONLNd⁄Rx^)< (°dONLNd‹Q]ç)D0°dONLNdfiRç^§)=24)°dONLNd„_<kR(áZCall:°dONLNdÍ^Ñjß)HA0-->°dONLNdÒ_kÓ)l3Entry to be removed from the AppleTalk event queue.°dONLNd%x<ÑQ(†ZThe °dONLNd)wQÉÇ)LRmvAEQ°dONLNd0xÇÑ1)1& call removes an entry, pointed to by °dONLNdVw1É?)ØA0°dONLNdXx?Ñ·)!, from the AppleTalk event queue.
  5646.     °dONLNd{ê{õî(∑ôMOVEQ°dONLNdÅê±õË)6 #LRmvAEQ,D0°dONLNdçêõ∞)U"; D0 = 24 code of LRmvAEQ LAP call°dONLNd±ö{•ô(¡ôMOVE.L°dONLNd∏ö±•Ì)6 LAPMgrPtr,An°dONLNd≈ö•Œ)U(; An -> start of LAP manager (from $B18)°dONLNdÔ§{Øä(ÀôJSR°dONLNdÛ§±ؘ)6LAPMgrCall(An)°dONLNd§Øø)U%; Call the LAP manager at entry point
  5647. °dONLNd(ª<«r(„ZLGetAEQ°dONLNd/ªr«y)6 (°dONLNd1∫yΔá)D0°dONLNd3ªá«û)=25)°dONLNd8»<‘_(ZReturn:°dONLNd@«Ñ”ß)HA1-->°dONLNdG»‘ƒ)l,Pointer to the AppleTalk event queue header.°dONLNdt·<ÌR(    ZThe °dONLNdx‡RÏÉ)LGetAEQ°dONLNd·ÉÌ˚)1 call returns a pointer in °dONLNdö‡˚Ï    )xA1°dONLNdú·    Ì˛)0 to the AppleTalk event queue header, previously°dONLNdÕÌ<˘m(Z
  5648. described.
  5649.     °dONLNdŸ{î+?MOVEQ°dONLNdfl±Ë)6 #LGetAEQ,D0°dONLNdÎ∞)U"; D0 = 25 code of LGetAEQ LAP call°dONLNd{ô(6ôMOVE.L°dONLNd±Ì)6 LAPMgrPtr,An°dONLNd#Œ)U(; An -> start of LAP manager (from $B18)°dONLNdM{$ä(@ôJSR°dONLNdQ±$˜)6LAPMgrCall(An)°dONLNd`$ø)U%; Call the LAP manager at entry point
  5650. °dONLNdÜ;<J•(fZThe Transitions
  5651. °dONLNdñW<c±*Each process is called at °dONLNd∞V±bÈ)uCallAddr°dONLNd∏WÈc©)8* when any significant transitions occur.  °dONLNd‚W©c˛)¿A value is passed°dONLNdÙc<oÆ(ãZMin, which indicates the nature of the event.  Additional parameters may also °dONLNdAcÆo˛(ãÃbe passed and a°dONLNdQo<{Ì(óZ'pointer to the task’s queue element is °dONLNdxoÌ{˛)±6also passed.  This is provided so processes may append°dONLNdØ{<áÛ(£Z]their own data structures (e.g., a globals pointer) at the end of the task record, which can °dONLNd     {Ûá˛(£be°dONLNd    á<ìå(ØZBreferenced when they are called.  Processes should follow the MPW °dONLNd    Qáåì˛(Ø™C register conventions. ¡X¡
  5652. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷˙11)
  5653.  of 15(ÏZM.NW.AppleTalkPhase2ˇfi◊#ˇ ˇˇˇˇ#◊ 
  5654. IR,Times
  5655. .+6-Macintosh Technical Notes /4/˘
  5656. °dONLNd*G*
  5657. Registers ,
  5658. Courier°dONLNd
  5659. G)U)/D0°dONLNd U*\), °dONLNd\)j)D1°dONLNdj*q), °dONLNdq))D2°dONLNd*Ü), °dONLNdÜ)î)A0°dONLNdî*Ø), and °dONLNdØ)Ω)A1°dONLNd Ω*—) are °dONLNd%—*⁄)8scratch registers that are not preserved by C functions.°dONLNd_*6b(R6AThe arguments passed to the process should be left on the stack, °dONLNd†*b6⁄(RÄsince the calling routine°dONLNd∫6B(^67removes them.  All other registers should be preserved.°dONLNdÚNZå*The Open Transition°dONLNdfrj*HFor AppleTalk open transitions, the process has the following interface:°dONLNdO~äO*@From assembly language, the stack upon calling looks as follows:
  5660.     °dONLNdêñ°E*    OpenEvent°dONLNdöñ`°~)HRECORD°dONLNd¢ñ®°≠)H0°dONLNd§†´J(«6
  5661. ReturnAddr°dONLNd؆`´t)HDS.L°dONLNdµ†®´≠)H1°dONLNd∑†Ã´+)$; address of caller°dONLNdÙµ@(—6theEvent°dONLNd’™`µt)HDS.L°dONLNd€™®µ≠)H1°dONLNd›™Ãµb)$; = 0 ; ID of Open transaction°dONLNd¸¥ø'(€6aqe°dONLNd¥`øt)HDS.L°dONLNd¥®ø≠)H1°dONLNd    ¥ÃøD)$; pointer to task record°dONLNd"æ…T(Â6 SlotDevParam°dONLNd/æ`…t)HDS.L°dONLNd5æ®…≠)H1°dONLNd7æÃ…q)$!; pointer to Open parameter block°dONLNd[»`”t(Ô~ENDR
  5662. °dONLNd`fiÍV(6
  5663. This routine °dONLNdmfiVÍÉ)>
  5664. is called °dONLNdwfiÉÍú)-only°dONLNd{fiúÍ⁄)= when the open routine for .MPP executes successfully.  Every°dONLNdπ͈õ(6Ventry in the transition queue is called in the same order that the entries were added °dONLNdÍõˆ⁄(π
  5665. to the queue.°dONLNd˜ (6$If AppleTalk is already open and an °dONLNdBˆ Ì)≤_Open°dONLNdG˜Ìv)# call is made, no process is °dONLNdd˜v⁄)âcalled.  The process°dONLNdyµ(,6#should return a function result in °dONLNdúµ√)ùD0°dONLNdû√J), which is currently ignored.°dONLNdº((D61A pointer to the open request parameter block is °dONLNdÌ(⁄)ˇ$passed to the open event process for°dONLNd(4(P6.information only (i.e., the event process may °dONLNd@(4⁄)ÿ0not prevent AppleTalk open calls).  Those fields°dONLNdq5Aá(]6which are of interest °dONLNdá5áAú)oare °dONLNdã4ú@)OpenPB->ioPermssn°dONLNdú5A©)w, passed by the caller, and °dONLNd∏4©@”)ñOpenPB°dONLNdæ4”@⁄)*-°dONLNdøAMB(j6>ioMix°dONLNd≈BBN )*, which is both passed by °dONLNdflB NΩ)à-the caller and updated by the .MPP open (see °dONLNd BΩN⁄)ÛInside°dONLNdNZI(v6    Macintosh°dONLNdNIZ)1#, Volume V, The AppleTalk Manager).°dONLNd@frè(é6The Close Transition°dONLNdU~äk*IFor AppleTalk close transitions, the process has the following interface:°dONLNdüñ¢O*@From assembly language, the stack upon calling looks as follows:
  5666.     °dONLNd‡ÆπJ*
  5667. CloseEvent°dONLNdÎÆ`π~)HRECORD°dONLNdÛÆ®π≠)H0°dONLNdı∏√J(fl6
  5668. ReturnAddr°dONLNd∏`√t)HDS.L°dONLNd∏®√≠)H1°dONLNd∏Ã√+)$; address of caller°dONLNd¬Õ@(È6theEvent°dONLNd&¬`Õt)HDS.L°dONLNd,¬®Õ≠)H1°dONLNd.¬ÃÕg)$; = 2 ; ID of Close transaction°dONLNdNÃ◊'(Û6aqe°dONLNdSÃ`◊t)HDS.L°dONLNdYî◊≠)H1°dONLNd[ÃÃ◊D)$; pointer to task record°dONLNdv÷`·t(˝~ENDR
  5669. °dONLNd{ϯŸ(6)The process is being told that AppleTalk °dONLNd§ÏŸ¯⁄)¡5is closing, which gives the process an opportunity to°dONLNd⁄¯ì( 6Uclose gracefully.  Every entry in the event queue is called, one after the other, in °dONLNd/¯ì⁄( ±the same order°dONLNd>ü(,6Rthat the entries were added to the queue.  The close action cannot be cancelled.  °dONLNdêü⁄(,Ω The process°dONLNdúµ(96#should return a function result in °dONLNdøµ√)ùD0°dONLNd¡√J), which is currently ignored.°dONLNdfl)5+(Q6-The ClosePrep and CancelClosePrep Transitions°dONLNd
  5670. BN0*The °dONLNdA0Mí)AtalkClosePrep°dONLNdBíNò)b °dONLNd BòN≈)and the °dONLNd(A≈MQ)-CancelAtalkClosePrep°dONLNd<BQN⁄)å control calls are used by°dONLNdWNZÀ(v6%various elements of the System, such °dONLNd|NÀZ⁄)≥7as the Chooser, to inform or query AppleTalk clients of°dONLNd¥Zfm(Ç6Gthe closing of network drivers.  For example, on a machine equipped to °dONLNd˚Zmf⁄(Çãgo to sleep or to wake°dONLNd    gs<(è6up, the °dONLNd    f<rf)$_Sleep°dONLNd     gfsk)* °dONLNd    !gks⁄)Ktrap is used by such entities as sleeptimer, Finder, and Shutdown to inform°dONLNd    msà(õ6AppleTalk clients that  °dONLNd    Ösà⁄)pDit is desirable for the the network driver (.MPP) to be closed.  The°dONLNd     ãB(®6_Sleep°dONLNd    –ÄBåG)* °dONLNd    —ÄGå÷)trap may be trying to do any °dONLNd    ÓÄ÷å⁄)è5of the following three things: request permission for ¡4¡˘
  5671. (÷612)
  5672.  of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ>◊#ˇ ˇˇˇˇ#◊ 
  5673. IR,Times
  5674. .+Z-Developer Support Center(-fi
  5675. December 1989 /X/
  5676. °dONLNd<)‰(EZ%sleep, alert for impending sleep, or °dONLNd%‰)˛)®9inform that wake up is underway.  The sleep request calls°dONLNd_)<5M(QZthe °dONLNdc)M5˛)Xfollowing two .MPP control calls; these calls are made before sleep queue procedures are°dONLNdº5<A[(]Zcalled.°dONLNdƒN<Z¶*The first control call, ,
  5677. Courier°dONLNd‹M¶Y)jAtalkClosePrep°dONLNdÍNZî)b, is used to inform or query °dONLNdNîZ˛)åAppleTalk clients that°dONLNdZ<f˝(ÇZbthe network driver might be closed in the very near future.  The call has the following interface:°dONLNdÅs<î*AtalkClosePrep°dONLNdèsîõ)X (°dONLNdërõ~Ô) csCode = 259°dONLNdùsÔÛ)T)
  5678.     °dONLNdüã<ñá(≤ZParameter Block°dONLNdØï<†Ç*
  5679.         --> 26°dONLNdæïü†Ω)ccsCode°dONLNd≈ï†)Qword°dONLNd ï8†¶)H;always AtalkClosePrep°dONLNd·ü<™Ç(ΔZ        <-- 28°dONLNdüü™—)c
  5680. clientName°dONLNd˚ü™)Qpointer°dONLNdü8™”)H;-> name of client using driver
  5681. °dONLNd#∂<¬x(fiZ Result codes°dONLNd0µÑ¡ß)HnoErr°dONLNd7∂¬Ï)l1The AppleTalk network driver (.MPP) may be closed°dONLNdk¬ÑŒº(΢closeErr°dONLNdu√œ˛)l5The AppleTalk network driver (.MPP) may not be closed°dONLNd´€<ÁÇ(Z
  5682. clientName°dONLNdµ‹ÇËY)F, is a pointer to an identifying string that °dONLNd·‹Y˲)◊!is returned only if the result is°dONLNdË<Ùt(ZcloseErr°dONLNd Ètı)8 .  Note that the pointer may be °dONLNd+ËÙ)íNIL°dONLNd.Èıv) in this case, while °dONLNdCÈvıfi)[the pointer is always °dONLNdYËfiÙÛ)hNIL°dONLNd\ÈÛı˛) if°dONLNd`ˆ<ê(Zthe return code is °dONLNdsıê≥)TnoErr°dONLNdxˆ≥∑)#.°dONLNdz<(7Z0All tasks in the AppleTalk Transition Queue are °dONLNd™Ö)‚called with the event °dONLNd¿Öƒ)g    ClosePrep°dONLNd…ƒ˛)? .  The tasks°dONLNd÷<'π(CZcan prevent driver closure °dONLNdÒπ'˛)}Ewith a negative response to the event call.  Each task is called with°dONLNd7'<3©(OZthe following interface:°dONLNdP?<Ks*@From assembly language, the stack upon calling looks as follows:
  5683.     °dONLNdëW<bi*    ClosePrep°dONLNdúW®bΔ)lRECORD°dONLNd§Wbı)H0°dONLNd¶Wbi)$;top of the stack°dONLNd∏a<ln(àZ
  5684. ReturnAddr°dONLNdƒa®lº)lDS.L°dONLNd alı)H1°dONLNdÃal_)$;addr of caller°dONLNd‹k<vd(íZtheEvent°dONLNdÊk®vº)lDS.L°dONLNdÏkvı)H1°dONLNdÓkv#)$;=3°dONLNdÚu<ÄK(úZaqe°dONLNd¯u®ĺ)lDS.L°dONLNd˛uÄı)H1°dONLNduÄP)$ ;->task rec.°dONLNd
  5685. <än(¶Z
  5686. clientName°dONLNd®äº)lDS.L°dONLNdäı)H1°dONLNd!äØ)$;ptr. to ptr. to name of client°dONLNdDâ®îº(∞ΔENDR
  5687. °dONLNdI†<¨Ñ(»ZFor this event, °dONLNdYüÑ´ÿ)H theEvent = 3°dONLNde†ÿ¨B)T, and the task is being °dONLNd}†B¨[)jboth°dONLNdņ[¨†) informed and °dONLNd膆¨˛)Easked if closing the°dONLNd§¨<∏·(‘Z"network driver is acceptable.  If °dONLNdΔ¨·∏˛)•9driver closure is acceptable, the task need only to reply°dONLNdπ<≈v(·Z
  5688. affirmative (°dONLNd
  5689. ∏vƒ†):D0 = 0°dONLNdπ†≈_)*+), or if not acceptable, deny the request (°dONLNd>∏_ƒâ)øD0 ≠ 0°dONLNdDπâ≈ó)*).  °dONLNdHπó≈˛)The task may use the°dONLNd]≈<—≠(ÌZevent as an opportunity °dONLNdu≈≠—˛)qCto “prepare to die” or may simply respond.  For example, a task may°dONLNdπ—<›Æ(˘ZOprevent further sessions from forming while waiting for the actual close event.°dONLNd    È<ıÇ*
  5690. clientName°dONLNdÍLjÿ)FH is a pointer to a field in the .MPP control call parameter block where °dONLNd[Íÿˆ˛(ˆthe task°dONLNddˆ<ê(ZJmay optionally store a string address.  This string identifies the client °dONLNdƈê˛(Æwho has AppleTalk in°dONLNd√<À(*ZTuse and is denying the request to close it.  This string may be used in a dialog to °dONLNdÀ˛(*È
  5691. inform the°dONLNd"<Ë(6Z[user to take appropriate action or explain why the requested action could not be performed.°dONLNd~&<2ü*If any task responds °dONLNdì&ü2˛)cJnegatively, no subsequent tasks are called.  Any tasks called prior to the°dONLNdfi3<?…([Zone that denied a query are °dONLNd˙3…?Z)çrecalled with another event, °dONLNd    2Z>Õ)ëCancelClosePrep °dONLNd    '3Õ?˛)s
  5692. (described°dONLNd    2?<KÅ(gZEbelow), enabling them to “undo preparations to die,” and the control °dONLNd    w?ÅK˛(gücall then completes with a°dONLNd    íK<Wt(tZcloseErr°dONLNd    öLtXí)8 error. ¡X¡
  5693. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷˙13)
  5694.  of 15(ÏZM.NW.AppleTalkPhase2ˇr◊#ˇ ˇˇˇˇ#◊ 
  5695. IR,Times
  5696. .+6-Macintosh Technical Notes /4/˘
  5697. °dONLNd)5O*$@From assembly language, the stack upon calling looks as follows:,
  5698. Courier
  5699.     °dONLNdAALc*CancelClosePrep°dONLNdQAÑL¢)lRECORD°dONLNdYAÃL—)H0°dONLNd[ALE)$;top of the stack°dONLNdmKVJ(r6
  5700. ReturnAddr°dONLNdyKÑVò)lDS.L°dONLNdKÃV—)H1°dONLNdÅKV;)$;addr of caller°dONLNdëU`@(|6theEvent°dONLNdõUÑ`ò)lDS.L°dONLNd°UÃ`—)H1°dONLNd£U`ˇ)$;=4°dONLNdß_j'(Ü6aqe°dONLNd≠_Ñjò)lDS.L°dONLNd≥_Ãj—)H1°dONLNdµ_j,)$ ;->task rec.°dONLNd≈iÑtò(ê¢ENDR
  5701. °dONLNd Äå`(®6For this event, °dONLNd⁄`ã∂)H theEvent = 4°dONLNdÊÄ∂å⁄)V>, and the task is being informed that although it has recently°dONLNd%åòÄ(¥6approved a request to °dONLNd;åÄò⁄)hGclose the network driver, a subsequent task in the AppleTalk Transition°dONLNdÉò§7(¿6:Queue has denied permission.  This event permits the task °dONLNdΩò7§⁄(¿Uto undo any processing that may°dONLNd›§∞ë(Ã6Mhave been performed in anticipation of the network driver being closed.  The °dONLNd*§ë∞⁄(ÃØprocess should°dONLNd9±Ωí(Ÿ6return a function result in °dONLNdU∞íº†)zD0°dONLNdW±†Ω'), which is currently ignored.°dONLNdu ÷®(Ú6The second new control call, °dONLNdí…®’4)êCancelAtalkClosePrep°dONLNd¶ 4÷<)å, °dONLNd® <÷⁄) is used to undo the effects of a°dONLNd…◊„M(ˇ6 successful °dONLNd‘÷M‚Ø)5AtalkClosePrep°dONLNd‚◊Ø„k)b( control call.  Even though all queried °dONLNd
  5702. ◊k„⁄)ºtasks in the AppleTalk°dONLNd!„ÔÒ( 6,Transition Queue approved of network driver °dONLNdM„ÒÔ⁄)Ÿ0closure, other conditions may exist after making°dONLNd~¸)(6the °dONLNdÇÔ)˚ã)AtalkClosePrep°dONLNdêã¸≤)b     control °dONLNdô≤¸⁄)'@call which prohibit network driver closure.  In this case, it is°dONLNd⁄¸z($6necessary to recall °dONLNdÓ¸z⁄)b@all tasks to undo any processing that may have been performed in°dONLNd/¨(06Vanticipation of the network driver being closed.  The control call to do this has the °dONLNdÖ¨⁄(0     following°dONLNdè C(<6
  5703. interface:°dONLNdö-9ñ*CancelAtalkClosePrep°dONLNdÆ-ñ9ù)~ (°dONLNd∞,ù8Ò) csCode = 260°dONLNdº-Ò9ı)T)
  5704.     °dONLNdæEPc(l6Parameter Block°dONLNdœOWZu+?
  5705. --> 26°dONLNd÷OüZΩ)HcsCode°dONLNd›O’ZÈ)6word°dONLNd‚O Zó)6;always CancelAtalkClosePrep
  5706. °dONLNdˇfrT(é6 Result codes°dONLNd e`qÉ)HnoErr°dONLNdfÃrl)lNothing could possibly go wrong°dONLNd3ã»(ß6&All tasks in the AppleTalk Transition °dONLNdY»ãc)∞ Queue are called with the event °dONLNdy~cäÃ)õCancelClosePrep°dONLNdàÃã⁄)i as°dONLNdåãóh(≥6described above.°dONLNdù§∞7*Note:°dONLNd£§<∞Ó)$!The use of the low-memory global °dONLNdƒ£ÓØ;)≤ ChooserBits°dONLNdœ§;∞∂)M ($946) is no longer an°dONLNdÁ∞<º(ÿZ)acceptable means of preventing AppleTalk °dONLNd∞º∂) !from closing when AppleTalk Phase°dONLNd2º<»®(‰ZH2 is present.  Transitions other than defined above must be ignored and °dONLNdzº®»∂(‰Δare°dONLNd~»<‘Z(Z?reserved for future implementation.  In the future transitions °dONLNdΩ»Z‘∂(xmay be defined for°dONLNd–‘<‡H(¸Z6notifying processes when a change in zone name occurs.
  5707. °dONLNd¯ˆ(#6 Potential Compatibility Problems
  5708. °dONLNd(fi* Using DDP and Talking to Routers°dONLNdI+7$*-If, for some reason, you need to talk to any °dONLNdv+$7⁄(SBrouter via DDP, always use the°dONLNdï7Cà(`6GetAppleTalkInfo°dONLNd•8àDº)pF call outlined in this Note to get the router’s actual 24-bit address.°dONLNdÏQ]-(y6The °dONLNdP-\e)WriteLAP°dONLNd¯Qe]ñ)8  function (°dONLNdPñ\«)1csCode °dONLNd
  5709. Q«]P)1= 243) to the .MPP driver is °dONLNd'QP]⁄)âno longer supported, since a°dONLNdD]iF(Ö6Anode is no longer identified only by its eight-bit (LAP) node ID. ¡4¡˘
  5710. *Q14)
  5711.  of 15(÷B)NW 3 - AppleTalk Phase 2 on the Macintosh+QM.NW.AppleTalkPhase2ˇ¯◊#ˇ ˇˇˇˇ#◊ 
  5712. IR,Times
  5713. .+Z-Developer Support Center(-fi
  5714. December 1989 /X/
  5715. °dONLNd<*Å(FZCOn a Macintosh running the AppleTalk Internet Router software, the ,
  5716. Courier°dONLNdCÅ)π(FüSelfSend°dONLNdKπ*—)8 flag °dONLNdQ—*˛)    is always°dONLNd[+<7ç(SZset, so if you try °dONLNdn+ç7)Qto clear this flag using the °dONLNdã*6c)Ç PSetSelfSend°dONLNdó+c7˛)T call (Inside Macintosh, Volume°dONLNd∑7<C…(_ZV-514), you will get an error.°dONLNd÷[<g¶*$Further Reference: ÜXܰdONLNdÈhNtR+
  5717. •°dONLNdÎh`t±)Inside AppleTalk°dONLNd¸tNÄR(úl•°dONLNd˛t`Äa)2Inside Macintosh, Volume II, The AppleTalk Manager°dONLNd1ÄNåR(®l•°dONLNd3Ä`åa)1Inside Macintosh, Volume V, The AppleTalk Manager°dONLNdeåNòR(¥l•°dONLNdgå`òX).EtherTalk and Alternate AppleTalk Connections °dONLNdïåXò˛)¯Reference, May 5, 1989—Draft°dONLNd≥ò`§~(¿~(DTS)°dONLNdπ§N∞R(Ãl•°dONLNdª§`∞E).AppleTalk Phase 2 Protocol Specification (DTS)°dONLNdÍ∞NºR(ÿl•°dONLNdÏ∞`º.)(Macintosh Portable Developer Notes (DTS) ¡X¡
  5718. (÷Z)NW 3 - AppleTalk Phase 2 on the Macintosh(÷˙15)
  5719.  of 15(ÏZM.NW.AppleTalkPhase2ˇ◊#ˇ ˇˇˇˇ#◊†Ç 
  5720. /ZÅ#
  5721.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5722. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5723. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5724. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5725. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5726.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5727. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5728. IR.°dONLNdn<ÅÕ(õZ,NW 4 - ASP and AFP Description Discrepancies
  5729. °dONLNd-Ä<èä*
  5730. Networking
  5731. °dONLNd9õ<ßq* Written by:°dONLNdEõÑß¡)H Mark Bennet°dONLNdQõ¡ß˛(√fl August 1988°dONLNd]≥<øN(€Z7The descriptions of the AppleTalk Session Protocol and °dONLNdî≥Nø˛(€l#AppleTalk Filing Protocol functions°dONLNd∏ø<Àn(ÁZ within the °dONLNd√ønÀ˛)2Rbody of the AppleTalk Manager chapter are incorrect and conflict with those in the°dONLNdÀ<◊¡(ÛZOSummary of the AppleTalk Manager. This technical note resolves the discrepancy. X°dONLNdf<¸N*%7The descriptions of the AppleTalk Session Protocol and °dONLNdùN¸˛(l#AppleTalk Filing Protocol functions°dONLNd¡¸<)($Z0which are described on pages 534 through 548 of °dONLNdÒ¸)≠)ÌInside Macintosh Volume V°dONLNd
  5732. ¸≠∞)Ñ °dONLNd ¸∞˛)conflict with the°dONLNd<x(0Z
  5733. descriptions °dONLNd*x˛)<Kin the Summary of the AppleTalk Manager section, pages 554 through 559. The°dONLNdv< &(<Z-descriptions in the Summary of the AppleTalk °dONLNd£& ˛)Í)Manager section are correct and should be°dONLNdÕ <,j(HZ    followed.°dONLNd◊8<D'**The Summary of the AppleTalk Manager does °dONLNd8'D˛)Î*not, however, present a description of the°dONLNd,D<P:(lZ4correct meaning of the arrows next to the parameter °dONLNd`D:P˛)˛'names in the function descriptions. The°dONLNdàP<\W(xZ8meaning of the arrows is equivalent to the one given to °dONLNd¿PW\˛(xu!them in the descriptions of other°dONLNd‚\<h¬(ÑZOperating System calls, i.e.:°dONLNdtÑÄ®+HArrow°dONLNd    tÄD)êMeaning,    Symbol°dONLNdåÑùê(∏¢Æ°dONLNdêúq)êParameter is passed°dONLNd,ùÑÆê(…¢¨°dONLNd1°≠x)êParameter is returned°dONLNdHÆÑøë(⁄¢´°dONLNdM≤æØ)ê Parameter is passed and returned°dONLNdn„<Ô¶( ZFurther Reference: X°dONLNdÅN¸R+
  5734. •°dONLNdÉ`¸“)The AppleTalk Manager ¡X¡
  5735. (÷Z,NW 4 - ASP and AFP Description Discrepancies(÷1) of 1(ÏZ
  5736. N.NW.ASPvsAFPˇ°¿Ù%%DSIDICT:_cv
  5737. currentdict /bu known {bu}if
  5738. userdict /_cv known not{userdict /_cv 30 dict put}if
  5739. _cv begin
  5740. /bdf{bind def}bind def
  5741. currentscreen/cs exch def/ca exch def/cf exch def
  5742. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5743. /ss{//cf //ca //cs setscreen}bdf
  5744. /stg{ss setgray}bdf
  5745. /strgb{ss setrgbcolor}bdf
  5746. /stcmyk{ss cvcmyk}bdf
  5747. /min1{dup 0 eq{pop 1}if}bdf
  5748. end
  5749. currentdict /bn known {bn}if
  5750. †øp◊#ˇ ˇˇˇˇ#◊†Ç 
  5751. /ZÅ#
  5752.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5753. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5754. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5755. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5756. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5757.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5758. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5759. IR.°dONLNdn<ÅÜ(õZ$NW 5 - High-Level AppleTalk Routines
  5760. °dONLNd%Ä<èä*
  5761. Networking
  5762. °dONLNd1õ<ßt* Revised by:°dONLNd>õ≈߲(√„
  5763. March 1988°dONLNdIß<≥q(œZ Written by:°dONLNdUßÑ≥’)HFred A. Huxham°dONLNddߌ≥˛(œÏMay 1987°dONLNdmø<ÀN(ÁZ9What you need to do in order to use high-level AppleTalk °dONLNd¶øNÀ˛(Ál$routines depends upon the interfaces°dONLNdÀÀ<◊3(ÛZ3you are using. Some differences are outlined below. X°dONLNdˇ<¸ö*%MPW before 2.0°dONLNd<^*When °dONLNd^˛)"Ncalling the old high-level AppleTalk routines, many programmers get mysterious°dONLNdb<!¢(=Z“resource not found” °dONLNdw¢!≥)f7errors (-192) from such seemingly harmless routines as ,
  5764. Courier°dONLNdÆ≥ ‰(=—MPPOpen°dONLNdµ‰!˛)1. The°dONLNdª!<-(IZ.resource that is not being found is ‘atpl’, a °dONLNdÈ!-˙)À4resource that contains all the glue code to the high°dONLNd!˙-˛)Û-°dONLNd-<9
  5765. (UZ/level routines. In order to use the high-level °dONLNdM-
  5766. 9˛)—2routines, your application must have this resource°dONLNdÄ9<E(aZ-in its resource fork. The ‘atpl’ resource is °dONLNd≠9E˛)◊.included in a file called “AppleTalk” with any°dONLNd‹E<Qw(mZDcompilers that use this outdated version of the AppleTalk interface.°dONLNd!]<i∞*MPW 2.0 and newer°dONLNd3u<Åg*A newer °dONLNd;ugŞ)+Vversion of the alternate interfaces is available in MPW 2.0; it includes bug fixes and°dONLNdíÅ<çÚ(©Zaincreased Macintosh II compatibility. With this version of the interface, the ‘atpl’ resource is °dONLNdÛÅÚç˛(©no°dONLNdˆç<ôU(µZ;longer used. Glue code is now linked into your application.°dONLNd2•<±≠*TThis will be the final release of the current-style interface. It will be supported °dONLNdÜ•≠±˛(ÕÀfor some time as°dONLNdó±<ΩN(ŸZthe °dONLNdõ±NΩπ)alternate interface.°dONLNdرπΩ%)k We have moved to a °dONLNd√±%Ω )l more straightforward and simple °dONLNd„± Ω˛)•    preferred°dONLNdÌΩ<…m(ÂZ    interface°dONLNdˆΩm…‡)1C, which is also implemented in MPW 2.0 and newer, and is described °dONLNd9Ω‡…˛(²in the°dONLNd@…<’Œ(ÒZAppleTalk Manager chapter of °dONLNd]…Œ’)íInside Macintosh°dONLNdm…’G)Q     vol. V. °dONLNdv…G’˛)(&Developers are free to continue to use°dONLNdù’<·y(˝Zthe alternate °dONLNd´’y·˛)=Ointerface, but in the long run it will be advantageous to move to the preferred°dONLNd˚·<Ìh(    Z
  5767. interface.°dONLNd˘<ª*Third Party Compilers°dONLNd<"*.Third party compilers use interfaces that are °dONLNdJ"˛)Ê'built from Apple’s MPW interfaces. Some°dONLNdr<)(EZ#compilers may not have upgraded to °dONLNdï)˛)¥7the new interfaces yet. Contact the individual compiler°dONLNdÕ)<5È(QZ#manufacturers for more information.°dONLNdÒY<e¶*0Further Reference: ÑXѰdONLNdfNrR+
  5768. •°dONLNdf`r“)The AppleTalk Manager°dONLNdrN~R(öl•°dONLNdr`~±)Inside AppleTalk°dONLNd/~NäR(¶l•°dONLNd1~`ä‚)AppleTalk Manager Update ¡X¡
  5769. (÷Z$NW 5 - High-Level AppleTalk Routines(÷1) of 1(ÏZM.NW.HighLevelAppleTalkˇ°¿Ù%%DSIDICT:_cv
  5770. currentdict /bu known {bu}if
  5771. userdict /_cv known not{userdict /_cv 30 dict put}if
  5772. _cv begin
  5773. /bdf{bind def}bind def
  5774. currentscreen/cs exch def/ca exch def/cf exch def
  5775. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5776. /ss{//cf //ca //cs setscreen}bdf
  5777. /stg{ss setgray}bdf
  5778. /strgb{ss setrgbcolor}bdf
  5779. /stcmyk{ss cvcmyk}bdf
  5780. /min1{dup 0 eq{pop 1}if}bdf
  5781. end
  5782. currentdict /bn known {bn}if
  5783. †ø∏◊#ˇ ˇˇˇˇ#◊†Ç 
  5784. /ZÅ#
  5785.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5786. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5787. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5788. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5789. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5790.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5791. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5792. IR.°dONLNdn<Å3(õZNW 6 - KillNBP Clarification
  5793. °dONLNdÄ<èä*
  5794. Networking
  5795. °dONLNd)õ<ßq* Written by:°dONLNd5õÑ߃)H Mark Bennett°dONLNdBõΩ߲(√€ August, 1988°dONLNdO≥<ø|(€Z@This technical note clears up some confusion regarding the Name °dONLNdè≥|ø˛(€öBinding Protocol KillNBP°dONLNd®ø<Àg(ÁZ    function. ˆXˆ°dONLNd≤Â<Òä*&The description °dONLNd¬ÂäÒ¨)Nof the ,
  5796. Courier°dONLNd…‰¨‰)"PKillNBP°dONLNd—‰Òg)8 function on page 519 of °dONLNdÍÂgÒÒ)ÉInside Macintosh Volume V°dONLNdÂÒÒ˛)ä is°dONLNdÚ<˛N(Z3somewhat confusing. The data type of the parameter °dONLNd:ÒN˝Ü(lthePBptr°dONLNdBÚܲö)8 is °dONLNdFÚö˛˛)incorrectly given as°dONLNd[˛<
  5797. t('ZATPPBPtr°dONLNdcˇt i)83 and the pointer to the queue element from the NBP °dONLNdñˇi ˛)ı!call to be aborted is incorrectly°dONLNd∏ <É(4Zgiven as being °dONLNd« É¥)G
  5798. passed in °dONLNd— ¥Ï)1aKillQEl°dONLNdŸ ÏÕ)80. The following is a correct description of the °dONLNd     Õ˛)·KillNBP°dONLNd<$f(@Z    function:°dONLNd<<H†*$KillNBP function°dONLNd,T<`•*?FUNCTION PKillNBP (thePBptr: MPPPBPtr; async: BOOLEAN) : OSErr;°dONLNdml`x¨+$Parameter block,    Symbol°dONLNdÑÑïê+$ưdONLNdÅà®î¥)$26°dONLNdÑàÃîÔ)$csCode°dONLNdãàî-)Hword°dONLNdêà8îê)$Always PKillNBP°dONLNd¢ïѶê(¡¢Æ°dONLNd§ô®•¥)$28°dONLNdßôÕˆ)$nKillQEl°dONLNd∞ô•5)Hpointer°dONLNd∏ô\•–)HPointer to queue element°dONLNd— <÷¶(ÚZFurther Reference: ıXı°dONLNd‰◊N„R+
  5799. •°dONLNdÊ◊`„“)The AppleTalk Manager ¡X¡
  5800. (÷ZNW 6 - KillNBP Clarification(÷1) of 1(ÏZ M.NW.KillNBPˇ°¿Ù%%DSIDICT:_cv
  5801. currentdict /bu known {bu}if
  5802. userdict /_cv known not{userdict /_cv 30 dict put}if
  5803. _cv begin
  5804. /bdf{bind def}bind def
  5805. currentscreen/cs exch def/ca exch def/cf exch def
  5806. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5807. /ss{//cf //ca //cs setscreen}bdf
  5808. /stg{ss setgray}bdf
  5809. /strgb{ss setrgbcolor}bdf
  5810. /stcmyk{ss cvcmyk}bdf
  5811. /min1{dup 0 eq{pop 1}if}bdf
  5812. end
  5813. currentdict /bn known {bn}if
  5814. †øí◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  5815. /ZÅ#
  5816.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5817. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5818. .WIQkWIQk+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5819. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5820. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5821.     l+&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5822. BÄ(Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É°dWORD†ç
  5823. IR.°dONLNdo<Çv(úZ"NW 7 - Avoid Use of Network Events
  5824. °dONLNd#Å<êä*
  5825. Networking
  5826. °dONLNd/®<¥t*$ Revised by:°dONLNd<®≈¥˛(–„
  5827. March 1988°dONLNdG¥<¿q(‹Z Written by:°dONLNdS¥Ñ¿«)H
  5828. Bryan Stearns°dONLNda¥œ¿˛(‹Ì    July 1987°dONLNdkÃ<ÿÑ(ÙZFuture System °dONLNdyÃÑÿ˛)HLsoftware enhancements will not support network events. This note gives hints°dONLNdΔÿ<‰\(Z;on weaning your application from the use of network events. X
  5829. °dONLNd    <Ë*4What are network events?
  5830. °dONLNd$<0Ù*UWhen the Event Manager was designed, an event number was reserved for future support °dONLNdp$Ù0˛(Lof°dONLNds0<<î(XZC“network events”. Later, when the AppleTalk Pascal Interfaces were °dONLNd∂0î<˛(X≤written, a completion°dONLNdÃ<<Hö(dZroutine was created °dONLNd‡<öH˛)^Fthat, when an asynchronous AppleTalk operation finished, would post an°dONLNd'I<Uu(qZ event using ,
  5831. Courier°dONLNd3HuTª)9
  5832. networkEvt°dONLNd=IªU€)F in the °dONLNdEH€T) evtNum°dONLNdKIU!)* field.°dONLNdSa<m‚(âZVOnly the AppleTalk Pascal Interfaces generate network events. Assembly-language users °dONLNd©a‚m˛(âof the°dONLNd∞m<y‘(ïZAppleTalk drivers (and those °dONLNdÕm‘y˛)ò9who called the AppleTalk drivers directly from high-level°dONLNdz<Üè(¢Zlanguages, using °dONLNdyèÖŒ)S    PBControl°dONLNd!zŒÜ—)? °dONLNd"z—ܲ)@calls) either provide a completion routine of their own, or poll°dONLNdcá<ìN(ØZthe °dONLNdgÜNíÜ)ioResult°dONLNdoáÜìı)8 field of the parameter °dONLNdááıìû)o!block passed with the call (when °dONLNd®Üûí÷)©ioResult°dONLNd∞á÷ì˛)8 became°dONLNd∏ì<üÔ(ªZ(negative or zero, the call is complete).
  5833. °dONLNd·∑<Δ˛*'Why not use network events?
  5834. °dONLNd˝“<fió*FIn some cases, network events can be lost. If the Event Manager finds °dONLNdC“ófi˛(˙µthat the queue is full°dONLNdZfi<ͪ(Zwhile posting an event, it °dONLNdufiªÍ˛)Bdiscards the oldest event. In a situation (such as a server) where°dONLNd∏Í<ˆ™(Zmultiple asynchronous °dONLNdŒÍ™ˆ˛)nDATP requests may complete at once, there is a chance that events may°dONLNdˆ<ñ(Zbe dropped off the °dONLNd&ˆñ˛)ZJend of the queue. This is more likely if the same machine is also handling°dONLNdq<N(*Z:user-interface events (like keypresses and mouse actions).°dONLNd¨<&fi*QAlso, in developing improvements to our operating system, it has become apparent °dONLNd˝fi&˛(B¸that to°dONLNd&<2Ó(NZWcontinue support of network events, we would have to compromise future enhancements to °dONLNd\&Ó2˛(N our°dONLNd`2<>e(ZZsystem. °dONLNdh2e>˛))OSo, future versions of the Macintosh operating system may ignore network events°dONLNd∏><J(fZ+instead of passing them to the application. ¡X¡
  5835. *p"NW 7 - Avoid Use of Network Events(÷1) of 2(ÏZM.NW.AvoidUseOfNetworkEventsˇ°¿Ù%%DSIDICT:_cv
  5836. currentdict /bu known {bu}if
  5837. userdict /_cv known not{userdict /_cv 30 dict put}if
  5838. _cv begin
  5839. /bdf{bind def}bind def
  5840. currentscreen/cs exch def/ca exch def/cf exch def
  5841. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5842. /ss{//cf //ca //cs setscreen}bdf
  5843. /stg{ss setgray}bdf
  5844. /strgb{ss setrgbcolor}bdf
  5845. /stcmyk{ss cvcmyk}bdf
  5846. /min1{dup 0 eq{pop 1}if}bdf
  5847. end
  5848. currentdict /bn known {bn}if
  5849. †ø    ◊#ˇ ˇˇˇˇ#◊ 
  5850. IR,Times
  5851. .+6-Macintosh Technical Notes /4/˘
  5852. °dONLNd)8≤*'How can I tell that my °dONLNd)≤8⁄)ö*calls have completed without using network°dONLNdB8GH(c6events?
  5853. °dONLNdJT`¥*As described on page II-275 of °dONLNdiT¥`)úInside Macintosh°dONLNdyT`f)S, you can poll the ,
  5854. Courier°dONLNdåSf_û)_abResult°dONLNdîTû`⁄)8
  5855.  field of the°dONLNd¢am5(â6call’s °dONLNd©`5l{)
  5856. ABusRecord°dONLNd≥a{mΔ)FD; when this value becomes negative or zero, the call has completed. °dONLNd˜aΔm⁄(â‰You°dONLNd˚my¬(ï6$can do this in your main event loop.°dONLNd Üíf*CWith this technique, you can ignore any network events returned by °dONLNdcÖfë∫(ÆÑ GetNextEvent°dONLNdoÜ∫í¬)T, °dONLNdqܬí⁄)since°dONLNdwíûa(∫6the AppleTalk °dONLNdÖíaû⁄)IKPascal Interfaces will be posting events anyway. If your application starts°dONLNd—û™ª(Δ6 enough asynchronous operations, °dONLNdÒûª™÷)£<it’s possible that their network events will cause other non°dONLNd-û÷™⁄(ΔÙ-°dONLNd.™∂Í(“6network events to be lost. °dONLNdI™Í∂⁄)“ To prevent this, you should call°dONLNdj∂¬Œ(fl6FlushEvents(networkMask,0)°dONLNdÑ∑Œ√)∂  frequently °dONLNdê∑√⁄):'to purge any accumulated network events°dONLNd∏√œ(Î6from the event queue.°dONLNdŒ€Áß*CYou may also consider using the new preferred high-level interface     °dONLNd€ßÁ⁄(≈
  5857. calls; see°dONLNdÁÛŸ(6$M.NW.AppleTalk for more information.°dONLNdA#Ç*0Further Reference: B4B˘°dONLNdT$*0.+
  5858. •°dONLNdV$<0ô)AppleTalk Manager°dONLNdh0*<.(XH•°dONLNdj0<<ì)M.NW.AppleTalk ¡4¡˘
  5859. (÷62) of 2(÷_"NW 7 - Avoid Use of Network Events+ M.NW.AvoidUseOfNetworkEventsˇ‹◊#ˇ ˇˇˇˇ#◊†Ç 
  5860. /ZÅ#
  5861.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5862. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5863. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5864. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5865. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5866.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5867. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5868. IR.°dONLNdn<Å (õZNW 8 - Opening AppleTalk
  5869. °dONLNdÄ<èä*
  5870. Networking
  5871. °dONLNd%õ<ßq* Written by:°dONLNd1õÑ߃)H Mark Bennett°dONLNd>õ∏߲(√÷
  5872. February 1989°dONLNdL≥<ø“(€ZNThis Technical Note describes the most effective, safe, and compatible way to °dONLNdö≥“ø˛(€open the°dONLNd£ø<ÀÈ(ÁZ!AppleTalk drivers, .MPP and .ATP. ˆXˆ°dONLNd≈‰<Ï*%YThe process of opening the AppleTalk drivers, .MPP and .ATP, can be greatly simplified.  °dONLNd‰Ï˛( 
  5873. The°dONLNd"Ò<˝◊(ZAppleTalk Manager chapters of °dONLNd@Ò◊˝))õInside Macintosh°dONLNdPÒ)˝É)R describe the calls ,
  5874. Courier°dONLNddɸ¥)ZMPPOpen°dONLNdkÒ¥˝Õ)1 and °dONLNdpÕ¸˛)ATPLoad°dONLNdx˝<    ¸(%Z'for use by high-level languages.  They °dONLNdü˝¸    ˛)¿1also describe the process of examining low-memory°dONLNd—
  5875. <c(2Zglobals °dONLNdŸ    cõ)'SPConfig°dONLNd·
  5876. õ∏)8 and °dONLNdÊ    ∏)PortBUse°dONLNdÓ
  5877. ?)8 before calling °dONLNd˛    ?b)O_Open°dONLNd
  5878. b˛)# for assembly language use of°dONLNd!<"q(>Z
  5879. AppleTalk.°dONLNd,.<:£*KStarting with the 128K ROM, the .MPP driver already has all the code built °dONLNdw.£:˛(V¡in for checking the°dONLNdã;<G£(cZlow-memory globals °dONLNdû:£F€)gSPConfig°dONLNd¶;€GÙ)8 and °dONLNd´:ÙF,)PortBUse°dONLNd≥;,Gr)8 before trying °dONLNd¬;rG¬)Fto complete the °dONLNd“:¬FÂ)P_Open°dONLNd◊;ÂG˛)# call.°dONLNdflG<S¢(oZHFurthermore, the .MPP driver will automatically open the .ATP driver as °dONLNd'G¢S˛(o¿part of its opening°dONLNd;S<_X({Z:process.  Therefore, since all of the required checks are °dONLNduSX_˛({v!made inside the driver itself, we°dONLNdó`<lº(àZrecommend that a simple °dONLNdØ_ºkfl)Ä_Open°dONLNd¥`flli)# call be made to the .MPP °dONLNdŒ`il˛)ädriver when you need to use°dONLNdÍl<x⁄(îZZAppleTalk.  In a high-level language like Pascal, this call would look like the following:
  5880.     °dONLNdFÑ`è+$%result := OpenDriver('.MPP', refnum);
  5881. °dONLNdlö<¶T(¬ZIn C:
  5882.     °dONLNds≤`Ω#+$'result = OpenDriver("\p.MPP", &refnum);
  5883. °dONLNdõ»<‘ª(ZAnd in assembly language:
  5884.     °dONLNdµ‡<ÎZ*openAT°dONLNdº‡rÎã)6SUB.W°dONLNd¬‡∫Î˚)H
  5885. #ioQElSize,SP°dONLNd–‡Î»)Z$; Make space for paramblock on stack°dONLNd˘Íı»*
  5886. $; since _Open is always synchronous.°dONLNd Ùˇ“*
  5887. &;  Using .W is slightly more efficient°dONLNdK˛    ◊*
  5888. '; and is safe since ioQElSize is small.°dONLNdtrê(/êMOVE.L°dONLNd{∫”)HSP,A0°dONLNdÅë)Z; Point A0 to paramblock.°dONLNdúrÅ(9êLEA°dONLNd†∫Ï)H
  5889. mppName,A1°dONLNd´ñ)Z; Point A1 to driver name.°dONLNd«r'ê(CêMOVE.L°dONLNdŒ∫'√)H5A1,ioFileName(A0); Put pointer to name in paramblock.°dONLNd&r1ã(MêCLR.B°dONLNd &∫1˚)H
  5890. ioPermssn(A0)°dONLNd&1◊)Z'; Clear so won't look like OpenDeskAcc.°dONLNdA0<;U(WZ_Open°dONLNdH:rEê+6
  5891. MOVE.W°dONLNdO:∫E)HioRefNum(A0),D1°dONLNd_:E“)Z&;You might want this later. Who knows?°dONLNdáDrOã(kêADD.W°dONLNdçD∫O˚)H
  5892. #ioQElSize,SP°dONLNdõDOë)Z; Reclaim space on stack.°dONLNd∂NrYÅ(uêRTS°dONLNdªNYñ)¢; D0 contains result code.°dONLNd÷b<m_(âZmppName°dONLNdfibrmÜ)6DC.B°dONLNd„b∫mø)H4°dONLNdÊlrwÜ(ìêDC.B°dONLNdÎl∫wÿ)H'.MPP' ¡X¡
  5893. (÷ZNW 8 - Opening AppleTalk(÷1) of 2(ÏZM.NW.OpenAppleTalkˇ°¿Ù%%DSIDICT:_cv
  5894. currentdict /bu known {bu}if
  5895. userdict /_cv known not{userdict /_cv 30 dict put}if
  5896. _cv begin
  5897. /bdf{bind def}bind def
  5898. currentscreen/cs exch def/ca exch def/cf exch def
  5899. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5900. /ss{//cf //ca //cs setscreen}bdf
  5901. /stg{ss setgray}bdf
  5902. /strgb{ss setrgbcolor}bdf
  5903. /stcmyk{ss cvcmyk}bdf
  5904. /min1{dup 0 eq{pop 1}if}bdf
  5905. end
  5906. currentdict /bn known {bn}if
  5907. †ø◊#ˇ ˇˇˇˇ#◊ 
  5908. IR,Times
  5909. .+6-Macintosh Technical Notes /4/˘
  5910. °dONLNd*ç*By using just the simple ,
  5911. Courier°dONLNdç)∞)u_Open°dONLNd∞*M)#" call to the .MPP driver, you can °dONLNd@M*⁄)ùensure that your code will be°dONLNd^*6◊(R6[compatible with future versions of AppleTalk that might not make use of low-memory globals.°dONLNd∫ZfÇ*0Further Reference: Ö4Ö˘°dONLNdÕg*s.+
  5912. •°dONLNdœg<sç)Inside Macintosh°dONLNdflgçs≤)Q8, Volumes II-261, IV-229, & V-507, The AppleTalk Manager ¡4¡˘
  5913. (÷62) of 2(÷àNW 8 - Opening AppleTalk+M.NW.OpenAppleTalkˇt◊#ˇ ˇˇˇˇ#◊†Ç 
  5914. /ZÅ#
  5915.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5916. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5917. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5918. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5919. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5920.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5921. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5922. IR.°dONLNdˇˇ(õZNW 9 - RegisterName
  5923. °dONLNdˇˇ*
  5924. Networking
  5925. °dONLNdˇˇ* Written by:°dONLNdˇˇ)H Mark Bennett°dONLNdˇˇ(√÷
  5926. February 1989°dONLNdˇˇ(‹Z The verify flag indicator byte (,
  5927. Courier°dONLNdˇˇ)ö
  5928. verifyFlag°dONLNdˇˇ)F) of the AppleTalk °dONLNdˇˇ)a RegisterName°dONLNdˇˇ)T     function°dONLNdˇˇ(ÈZshould always be set °dONLNdˇˇ)eTRUE°dONLNdˇˇ) in published code. ¯X¯°dONLNdˇˇ(ZThe AppleTalk chapter of °dONLNdˇˇ)õInside Macintosh°dONLNdˇˇ)Y,     °dONLNdˇˇ) Volume II-322, in describing the°dONLNdˇˇ(Z RegisterName°dONLNdˇˇ)T function, states:°dONLNdˇˇ(3~I“If verifyFlag is TRUE, RegisterName checks on the network to see if the °dONLNdˇˇ(3flname°dONLNdˇˇ(?~Dis already in use, and returns a result code of nbpDuplicate if so.”°dONLNdˇˇ(XZ
  5929. Note that °dONLNdˇˇ).
  5930. verifyFlag°dONLNdˇˇ)F should °dONLNdˇˇ)&always°dONLNdˇˇ)' be °dONLNdˇˇ)TRUE°dONLNdˇˇ) in published code.  The °dONLNdˇˇ)udesign of the Name°dONLNdˇˇ(eZ@Binding Protocol (NBP) requires that an entity name be unique.  °dONLNdˇˇ(eòThe way °dONLNdˇˇ)0 RegisterName°dONLNdˇˇ(qZDensures this uniqueness is by broadcasting a lookup request for the °dONLNdˇˇ(q§registered name.  If any°dONLNdˇˇ(~Zentity responds, then °dONLNdˇˇ)f RegisterName°dONLNdˇˇ)T knows °dONLNdˇˇ)&-that the name would not be unique and returns°dONLNdˇˇ(äZ;an error.  Some developers, in anticipating the time delay °dONLNdˇˇ(ät!involved in broadcasting a lookup°dONLNdˇˇ(óZ6request and waiting for a response, have opted to set °dONLNdˇˇ(ó_
  5931. verifyFlag°dONLNdˇˇ)F to °dONLNdˇˇ)FALSE°dONLNdˇˇ)#, not °dONLNdˇˇ)    realizing°dONLNdˇˇ(£Z!the potential danger in doing so.°dONLNdˇˇ*Apple provides °dONLNdˇˇ)K
  5932. verifyFlag°dONLNdˇˇ)F2 for experimental or developmental purposes, such °dONLNdˇˇ)Ú as narrowing°dONLNdˇˇ(»Z;down a problem in registering a name on a network.  Always °dONLNdˇˇ(»~make sure that code which ships°dONLNdˇˇ(’Zhas °dONLNdˇˇ)
  5933. verifyFlag°dONLNdˇˇ)F set to °dONLNdˇˇ)TRUE°dONLNdˇˇ).°dONLNdˇˇ(ZFurther Reference: X°dONLNdˇˇ+
  5934. •°dONLNdˇˇ)Inside Macintosh°dONLNdˇˇ)Q&, Volume II-261, The AppleTalk Manager ¡X¡
  5935. (÷ZNW 9 - RegisterName(÷1) of 1(ÏZM.NW.RegisterNameˇ°¿Ù%%DSIDICT:_cv
  5936. currentdict /bu known {bu}if
  5937. userdict /_cv known not{userdict /_cv 30 dict put}if
  5938. _cv begin
  5939. /bdf{bind def}bind def
  5940. currentscreen/cs exch def/ca exch def/cf exch def
  5941. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5942. /ss{//cf //ca //cs setscreen}bdf
  5943. /stg{ss setgray}bdf
  5944. /strgb{ss setrgbcolor}bdf
  5945. /stcmyk{ss cvcmyk}bdf
  5946. /min1{dup 0 eq{pop 1}if}bdf
  5947. end
  5948. currentdict /bn known {bn}if
  5949. †ø¿◊#ˇ ˇˇˇˇ#◊†Ç 
  5950. /ZÅ#
  5951.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5952. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5953. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  5954. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  5955. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  5956.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  5957. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  5958. IR.°dONLNdn<Å∫(õZ*NW 10 - AppleShare Foreground Applications
  5959. °dONLNd+Ä<èä*
  5960. Networking°dONLNd6Ägè˛(´ÖM.NW.AppleShareApp
  5961. °dONLNdIõ<ßt(√Z Revised by:°dONLNdUõÑß∑)H
  5962. Jim Luther°dONLNd`õœß˛(√Ì    July 1992°dONLNdjß<≥q(œZ Written by:°dONLNdvßÑ≥’)HFred A. Huxham°dONLNdÖßr≥˛)ÓNovember 1987–March 1988°dONLNdûø<À (ÁZThis Technical Note outlines °dONLNdªø À˛)é=the requirements and restrictions of an AppleShare foreground°dONLNd˘À<◊R(ÛZ;application (AppleShare foreground applications are called °dONLNd4ÀR◊ß(Ûpconcurrent server °dONLNdFÀß◊fl)U applications°dONLNdRÀfl◊˛)8 in the°dONLNdZ◊<„≠(ˇZAppleShare File Server °dONLNdq◊≠„)qAdministrator’s Guide°dONLNdÜ◊„˛)k/). This information pertains only to AppleShare°dONLNd∂„<ÔC( Z5system software versions 1.1 through 2.0. AppleShare °dONLNd΄CÔ˛( a&version 3.0 and Macintosh file sharing°dONLNdÔ<˚‘(Zrun under Macintosh System 7. °dONLNd0Ô‘˚˛)ò<AppleShare foreground applications are not necessary and are°dONLNdm˚<|(#ZBnot supported by AppleShare version 3.0 or Macintosh file sharing.°dONLNd∞<ÿ*Changes since March 1988:°dONLNd…ÿ€)ú °dONLNd €˛): Added note that AppleShare version 3.0 and Macintosh file°dONLNd<+&(GZ,sharing don’t support AppleShare foreground °dONLNd1&+˛)Í*applications. Added additional notes about°dONLNd\+<7Í(SZ#AppleShare foreground applications. bXb°dONLNdÄP<\®*%JAn AppleShare server requires a dedicated Macintosh. The server, however, °dONLNd P®\˛(xΔis implemented as°dONLNd‹\<h(ÑZ-an interrupt-driven application that runs in °dONLNd    \h˛)…2the system heap of the server machine. This allows°dONLNd<h<t(êZ`the running of a concurrent or foreground application that will live in the application heap of °dONLNdúht˛(êthe°dONLNd†t<Ä€(úZVserver machine. An example of a foreground application is LaserShare, the LaserWriter °dONLNdˆt€Ä˛(ú˘spooler°dONLNd˛Ä<å¢(®Zavailable from Apple.°dONLNdò<§n*:An AppleShare foreground application has a few additional °dONLNdNòn§˛(¿årestrictions and requirements°dONLNdl§<∞(ÃZ.beyond that of a normal Macintosh application:°dONLNdõº<»X*1. In °dONLNd°ºX»˛)Sorder for AppleShare to recognize your program as a foreground application, it must°dONLNdı…<’∏(ÒZcontain a resource of type ,
  5963. Courier°dONLNd»∏‘‚)|'fgnd'°dONLNd…‚’É)*!, ID=1, containing a longword of °dONLNd7»É‘¬)°    $00000000°dONLNd@…¬’Δ)?.°dONLNdB·<Ì¿(    Z2. Do not make any file °dONLNdZ·¿Ì˛)Ñ<system calls outside of server volumes’ Server Folders. If a°dONLNdóÌ<˘˘(Z\foreground application needs to create files, it is recommended that the application create °dONLNdÛÌ˘˘˛(a°dONLNdı˘<z(!Zfolder inside °dONLNd˘z˛)>Tthe Server Folder and then create all its files within that folder. For example, all°dONLNdX<ã(-Zprint spooler or °dONLNdiã˛)OKE-mail files must reside within the Server Folder, and preferably, within a°dONLNdµ<n(9ZCfolder that is inside the Server Folder. To find the Server Folder,°dONLNd˘*N6R+•°dONLNd˚*W6|)    Make a °dONLNd)|5…)% PBHGetVlnfo°dONLNd
  5964. *…6&)M call on the volume.°dONLNd"7NCR(_l•°dONLNd$7WCÉ)    Examine °dONLNd,6ÉBÏ),ioVFndrInfo[8] °dONLNd;7ÏC0)i(long integer).°dONLNdKDNPR(ll•°dONLNdMDWPb)    If °dONLNdPCbOƒ) ioVFndrInfo[8]°dONLNd^DƒP√)b9 is nonzero, it is the directory ID of the Server Folder.°dONLNdò\<hà(ÑZ3. Do not make °dONLNdß\àh˛)LMfile system calls or in any way modify the AppleShare server application, the°dONLNdıh<t˛(êZ*Parallel Directory Structure, or the user °dONLNd    h˛t˛)¬2or group databases within the Server Folder of any°dONLNd    Rt<ÄF(úZ8volume. Also, do not rely on the presence or formats of °dONLNd    ätFIJ(úd(these structures, as they are subject to°dONLNd    ≥Ä<åa(®Zchange! ¡X¡
  5965. *.*NW 10 - AppleShare Foreground Applications(÷1) of 2(ÏZM.NW.AppleShareAppˇ°¿Ù%%DSIDICT:_cv
  5966. currentdict /bu known {bu}if
  5967. userdict /_cv known not{userdict /_cv 30 dict put}if
  5968. _cv begin
  5969. /bdf{bind def}bind def
  5970. currentscreen/cs exch def/ca exch def/cf exch def
  5971. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  5972. /ss{//cf //ca //cs setscreen}bdf
  5973. /stg{ss setgray}bdf
  5974. /strgb{ss setrgbcolor}bdf
  5975. /stcmyk{ss cvcmyk}bdf
  5976. /min1{dup 0 eq{pop 1}if}bdf
  5977. end
  5978. currentdict /bn known {bn}if
  5979. †ø◊#ˇ ˇˇˇˇ#◊ 
  5980. IR,Times
  5981. .+6-Macintosh Technical Notes /4/˘
  5982. °dONLNd)5@*$@4. Do not eject or unmount a volume that is not in drive 1 or 2.°dONLNdABNl*5. Do not call the ,
  5983. Courier°dONLNdTAlM§)TShutdown°dONLNd\B§N-)8  trap; instead, quit by calling °dONLNd|A-Mz)â ExitToShell°dONLNdáBzN⁄)M or by dropping out°dONLNdõNZÖ(v6of the main event loop.°dONLNd≥frö*UIn addition to these restrictions, here are a few other things that are good to know °dONLNdför⁄(é∏ when writing°dONLNdr~œ(ö6%an AppleShare foreground application.
  5984. °dONLNd;ñ•*'2Multiple AppleShare Foreground Application Support
  5985. °dONLNdn±Ω*-Although you can install multiple AppleShare °dONLNdõ±Ω⁄)Î(foreground applications on an AppleShare°dONLNdƒΩ…¿(Â6Qserver, only one can be active at a time. Since the AppleShare Admin application °dONLNdΩ¿…⁄(Âfiis an°dONLNd…’‡(Ò6)AppleShare foreground application, users °dONLNdD…‡’⁄)»3will have to quit Admin to run your application and°dONLNdx’·ø(˝6#quit your application to run Admin.
  5986. °dONLNdú˘Ë*'Number of Open Files Allowed
  5987. °dONLNdπ q*FAny files opened by an AppleShare foreground application count toward °dONLNdˇq ⁄(<èthe maximum number°dONLNd , (H65of open files allowed on the AppleShare file server. °dONLNdG  ,⁄(H>"See Macintosh Technical Note #216,°dONLNdj,8È(T6*“AppleShare and File-Sharing Limits,” for °dONLNdî,È8⁄)—0the number of open files allowed on a particular°dONLNd≈8DÖ(`6AppleShare file server.
  5988. °dONLNd›\k–*'How Much Memory Does °dONLNdÚ\–k⁄)∏#an AppleShare Foregound Application°dONLNdkz6(ñ6Get?
  5989. °dONLNdÜí∑*QForeground applications are launched by an AppleShare file server, so AppleShare °dONLNdlÜ∑í⁄(Æ’decides°dONLNdtíûŒ(∫6\how big your application heap will be. First AppleShare reads your 'SIZE' resource. It uses °dONLNd–íŒû⁄(∫ÏID°dONLNd”û™˛(Δ600 (the Finder-created 'SIZE' resource) if it is °dONLNdû˛™⁄)Ê,available. It uses ID -1 (the default 'SIZE'°dONLNd0™∂É(“6Oresource created by the programmer) if ID 0 isn’t available. It uses any other °dONLNd™É∂⁄(“°'SIZE' resource it°dONLNdí∂¬≈(fi6Xcan find if IDs 0 and-1 aren’t there. If no 'SIZE' resources are found, then AppleShare °dONLNdÍ∂≈¬⁄(fi„uses°dONLNdÔ¬ŒS(Í6B196 KB for the size and the minimum size. If your application has °dONLNd1¬SŒ⁄(Íqa 'SIZE' less than 128 KB,°dONLNdLŒ⁄(ˆ66then 128 KB is used for the size and the minimum size.°dONLNdÉÊÚ“*]AppleShare then attempts to allocate the minimum size for your application (as found above). °dONLNd‡Ê“Ú⁄(If°dONLNd„Ú˛?(6;successful, AppleShare sets the system cache to 32 KB (the °dONLNdÚ?˛⁄(]minimum). (At this point, your°dONLNd=˛
  5990. ;(&6<application could still be launched if any of the following °dONLNdy˛;
  5991. ⁄(&Ythings fail.)  Then, AppleShare°dONLNdô
  5992. y(26Eattempts to allocate the default size for your application (as found °dONLNdfi
  5993. y⁄(2óabove). After that,°dONLNdÚ"V(>6?AppleShare gives any remaining memory back to the system cache.°dONLNd2FRÇ*0Further Reference: q4q˘°dONLNdES*_.+
  5994. •°dONLNdGS<_),AppleShare File Server Administrator’s Guide°dONLNdt_*k.(áH•°dONLNdv_<kÉ)AMacintosh Technical Note #216, AppleShare and File-Sharing Limits ¡4¡˘
  5995. (÷62) of 2(÷>*NW 10 - AppleShare Foreground Applications+\M.NW.AppleShareAppˇ6◊#ˇ ˇˇˇˇ#◊†Ç 
  5996. /ZÅ#
  5997.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  5998. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  5999. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  6000. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  6001. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  6002.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  6003. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  6004. IR.°dONLNdn<Å≤(õZ*NW 11 - AppleShare and File-Sharing Limits
  6005. °dONLNd+Ä<èä*
  6006. Networking°dONLNd6ÄWè˛(´uM.NW.AppleShareLimits
  6007. °dONLNdLõ<ßt(√Z Revised by:°dONLNdXõÑß∑)H
  6008. Jim Luther°dONLNdcõœß˛(√Ì    July 1992°dONLNdmß<≥q(œZ Written by:°dONLNdyßÑ≥ƒ)H Mark Bennett°dONLNdÜßæ≥˛(œ‹ October 1988°dONLNdìø<Àô(ÁZ?This Technical Note describes some machine-dependent limits of °dONLNd“øôÀ˛(Á∑current versions of°dONLNdÊÀ<◊Q(ÛZ;AppleShare file servers (including Macintosh file sharing).°dONLNd"„<Ô·*Changes since October 1988:°dONLNd=„·Ô€)•2 Added information for AppleShare system software °dONLNdo„€Ô˛)˙version°dONLNdwÔ<˚–(Z3.0 and Macintosh file sharing. &X&°dONLNdó< ]*%>The following chart lists some current AppleShare limits that °dONLNd’] ˛(<{ are based upon the chosen server°dONLNdˆ <,(HZ'platform and memory configuration. The °dONLNd ,˛)ÿ+limits that otherwise might be present on a°dONLNdI,<8Ò(TZ(workstation are still in effect and are °dONLNdq,Ò8˛)µ5not affected by the workstation being logged on to an°dONLNdß8<DL(`Z:AppleShare server. These limits will change in the future.
  6009. °dONLNd‚\<k*'AppleShare 1.1 and 2.0 Limits
  6010. °dONLNdwÉ+¥Server:°dONLNd    wÄÉ©)êServer:°dONLNdÉèe(´Macintosh Plus, SE,°dONLNd&ÉÄèÁ)êMacintosh II With°dONLNd8è<õØ(∑ZDescription of Limit°dONLNdMèõL)¥or II With 1 MB°dONLNd]èÄõ‡)êMore Than 1 MB ∫X∫°dONLNdlú<®è(ƒZNumber of Users°dONLNd|ú®¸)¥25°dONLNdúÄ®å)ê50°dONLNdÇ®<¥º(–ZNumber of Locked Ranges°dONLNdö®¥)¥1000°dONLNdü®Ä¥ò)ê2000°dONLNd§¥<¿¶(‹ZNumber of Open Files°dONLNdπ¥¿¸)¥80°dONLNdº¥Ä¿í)ê160°dONLNd¿¿<Ãù(ËZNumber of Volumes°dONLNd“¿ø)¥16°dONLNd’¿ÄÃå)ê16
  6011. °dONLNdÿ‰<Ûé(Z0AppleShare 3.0 and Macintosh File-Sharing Limits
  6012. °dONLNd
  6013. ˇ 3+¥ File Server:°dONLNdˇÄ √)ê File Server:°dONLNd$ <Ø(3ZDescription of Limit°dONLNd9 t)¥Macintosh File Sharing°dONLNdP Äÿ)êAppleShare 3.0 6X6°dONLNd_<$è(@ZNumber of Users°dONLNdo$¸)¥10°dONLNdrÄ$ò)ê120*°dONLNdw$<0º(LZNumber of Locked Ranges°dONLNdè$0)¥200°dONLNdì$Ä0û)ê2400*°dONLNdô0<<¶(XZNumber of Open Files°dONLNdÆ0<)¥346*°dONLNd≥0Ä<û)ê346**°dONLNdπ<<HØ(dZNumber of Share Points°dONLNd–<H¸)¥10°dONLNd”<ÄHå)ê50°dONLNd÷T<`B(|Z*°dONLNdÿTN``)4The maximum number of users supported by AppleShare °dONLNd T``˛(|~ version 3.0 can be adjusted with°dONLNd-`NlD(àl-the AppleShare Admin application or with the ,
  6014. Courier
  6015. °dONLNdZ`Dlò)ˆSCSetSetupInfo
  6016. °dONLNdh`òl˛)T AppleShare Server°dONLNd{lNxß(îlIControl call. AppleShare version 3.0 allocates 20 locked ranges per user. ¡X¡
  6017. (÷Z*NW 11 - AppleShare and File-Sharing Limits(÷1) of 2(ÏZM.NW.AppleShareLimitsˇ°¿Ù%%DSIDICT:_cv
  6018. currentdict /bu known {bu}if
  6019. userdict /_cv known not{userdict /_cv 30 dict put}if
  6020. _cv begin
  6021. /bdf{bind def}bind def
  6022. currentscreen/cs exch def/ca exch def/cf exch def
  6023. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  6024. /ss{//cf //ca //cs setscreen}bdf
  6025. /stg{ss setgray}bdf
  6026. /strgb{ss setrgbcolor}bdf
  6027. /stcmyk{ss cvcmyk}bdf
  6028. /min1{dup 0 eq{pop 1}if}bdf
  6029. end
  6030. currentdict /bn known {bn}if
  6031. †ø∂◊#ˇ ˇˇˇˇ#◊ 
  6032. IR,Times
  6033. .+6-Macintosh Technical Notes /4/˘
  6034. °dONLNd)$***°dONLNd*)∑)This is the maximum number °dONLNd∑)⁄)ç;of file control blocks (FCBs) allowed by the Macintosh File°dONLNdZ)*5ª(QHManager. The system and any °dONLNdv)ª5⁄)ë;applications running on the server Macintosh (including the°dONLNd≤5*A(]H3file server) will use some of those available FCBs.°dONLNdÊeqÇ(ç6Further Reference: ê4ê˘°dONLNd˘r*~.+
  6035. •°dONLNd˚r<~),AppleShare File Server Administrator’s Guide°dONLNd(~*ä.(¶H•°dONLNd*~<äâ)AMacintosh Technical Note #167, AppleShare Foreground Applications ¡4¡˘
  6036. (÷62) of 2(÷A*NW 11 - AppleShare and File-Sharing Limits+OM.NW.AppleShareLimitsˇ¨◊#ˇ ˇˇˇˇ#◊†Ç 
  6037. /ZÅ#
  6038.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  6039. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  6040. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  6041. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  6042. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  6043.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  6044. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  6045. IR.°dONLNdn<Å¡(õZ,NW 12 - AppleShare-able Applications and the°dONLNd-Ä<ì‘*Resource Manager
  6046. °dONLNd>í<°ä*
  6047. Networking
  6048. °dONLNdJ≠<πt* Revised by:°dONLNdW≠≈π˛(’„
  6049. March 1988°dONLNdbπ<≈q(·Z Written by:°dONLNdnπÑ≈«)H
  6050. Bryan Stearns°dONLNd|π≈≈˛(·„
  6051. March 1987°dONLNdá—<›(˘Z(Normally, applications on an AppleShare °dONLNdØ—›˛)Δ1server volume cannot be executed by more than one°dONLNd·›<ÈL(Z<user at a time. This technical note explains why, and tells °dONLNd›LÈ˛(j#how you can enable your application°dONLNdAÈ<ıy(Z
  6052. to be shared.  X °dONLNdO<1*%(The Resource Manager versus Shared Files°dONLNdx&<2>*4Part of the explanation of why applications are not °dONLNd¨&>2˛(N\&automatically sharable is based on the°dONLNd”2<>¨(ZZHdesign of the Resource Manager.  The Resource Manager is a great little °dONLNd2¨>˛(Z database. It was°dONLNd,><J¥(fZoriginally conceived as °dONLNdD>¥J˛)x?a way to keep applications localizable (a task it has performed°dONLNdÑJ<Vå(rZ@admirably), and was found to be an excellent foundation for the °dONLNdƒJåV˛(r™Segment Loader, Font°dONLNdŸV<bè(~ZHManager, and a large part of the rest of the Macintosh operating system.°dONLNd"n<z’*NHowever, it was never designed to be a multi-user database. When the Resource °dONLNdpn’z˛(ñÛManager°dONLNdxz<Ü((¢Z3opens a resource file (such as an application), it °dONLNd´z(ܲ)Ï*reads the file’s resource map into memory.°dONLNd÷Ü<ív(ÆZ@This map remains in memory until the resource file is closed by °dONLNdÜví˛(Æîthe Segment Loader, which°dONLNd0í<ûµ(∫ZOregains control when the application exits. Sometimes it is necessary to write °dONLNdíµû˛(∫”the map out to°dONLNdéü<´Á(«Z%disk; normally, this is only done by ,
  6053. Courier°dONLNd≥ûÁ™B)´
  6054. UpdateResFile°dONLNd¿üB´Y)[ and °dONLNd≈ûY™≠) CloseResFile°dONLNd—ü≠´±)T.°dONLNd”∑<√(flZ+If two users opened the same resource file °dONLNd˛∑√˛) 2at the same time, and one of them had write access°dONLNd1√<œÍ(ÎZ(to the file and added a resource to it, °dONLNdY√Íœ˛)Æ5the other user’s Resource Manager wouldn’t know about°dONLNdèœ<€_(˜ZAit; this would make the other user’s copy of the file’s original °dONLNd–œ_€˛(˜} resource map invalid. This could°dONLNdÒ€<Án(ZCcause (at least) a crash; if both users had write access, it’s not °dONLNd4€nÁ˛(åunlikely that the resource file°dONLNdTÁ<Û(Z'involved would become corrupted. Also, °dONLNd{ÁÛ˛)≈3although you can tell the Resource Manager to write°dONLNdØÛ<ˇ‚(Z\out an updated resource map, there’s no way for another user to tell it to refresh the copy °dONLNd Û‚ˇ˛(of the°dONLNdˇ< ‡('Z"map in memory if the file changes.°dONLNd5<#≠*@What does all this have to do with running my application twice?°dONLNdv/<;◊*ZYour application is stored as a resource file; code segments, alert and dialog templates, °dONLNd–/◊;˛(Wı    etc., are°dONLNd⁄;<GU(cZ<resources. If you write to your application’s resource file °dONLNd;UG˛(cs#(for instance, to add configuration°dONLNd:G<So(oZCinformation, like print records), your application can’t be shared.°dONLNd~_<kø*QIn Apple’s compatibility testing of existing applications (during development of °dONLNdœ_øk˛(á› AppleShare),°dONLNd‹k<wñ(ìZwe found quite a °dONLNdÌkñw˛)ZEfew applications, some of them quite popular, that wrote to their own°dONLNd    3w<É=(üZ5resource files. So we decided, to improve the safety °dONLNd    hw=ɲ(ü[%of using AppleShare, to always launch°dONLNd    éÉ<è¥(´ZNapplications using a combination of access privileges such that only one user °dONLNd    ‹É¥è˛(´“at a time could ¡X¡
  6055. (÷Z=NW 12 - AppleShare-able Applications and the Resource Manager(÷1) of 3(ÏZM.NW.AppleShareableAppsˇ°¿Ù%%DSIDICT:_cv
  6056. currentdict /bu known {bu}if
  6057. userdict /_cv known not{userdict /_cv 30 dict put}if
  6058. _cv begin
  6059. /bdf{bind def}bind def
  6060. currentscreen/cs exch def/ca exch def/cf exch def
  6061. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  6062. /ss{//cf //ca //cs setscreen}bdf
  6063. /stg{ss setgray}bdf
  6064. /strgb{ss setrgbcolor}bdf
  6065. /stcmyk{ss cvcmyk}bdf
  6066. /min1{dup 0 eq{pop 1}if}bdf
  6067. end
  6068. currentdict /bn known {bn}if
  6069. †øà◊#ˇ ˇˇˇˇ#◊ 
  6070. IR,Times
  6071. .+6-Macintosh Technical Notes /4/˘
  6072. °dONLNd)÷**use a given application (these privileges °dONLNd*÷)⁄)æ7will be discussed in a future Technical Note). In fact,°dONLNdb)5ã(Q6GAppleShare opens all resource files this way, unless the resource file °dONLNd©)ã5⁄(Q©is opened with,
  6073. Courier°dONLNd∏5A^(^6
  6074. OpenRFPerm°dONLNd¬6^B)F' and read-only permission is specified.°dONLNdÍNZ(v6+But my application doesn’t write to itself!°dONLNdfr∏*"We realize that many applications °dONLNd8f∏r⁄)†;do not. However, there are other considerations (covered in°dONLNdtr~m(ö6Edetail, with suggestions for fixes, in “Application Development in a °dONLNdπrm~⁄(öãShared Environment”,°dONLNdŒ~äe(¶6Eavailable from APDA ). In brief, here are the big ones we know about:°dONLNdñ*¢.+•°dONLNdñ7¢)
  6075. -Does your application create temporary files °dONLNdCñ¢∂)ÿ!with fixed names in a fixed place°dONLNde¢7ÆÓ( U#(such as the  directory containing °dONLNdà¢ÓÆ∂)∑&the application)? Without AppleShare’s°dONLNdØÆ7∫Ø(÷UQprotection, two applications  to use the same temporary file could be disastrous.°dONLNdΔ*“.(ÓH•°dONLNdΔ7“\)
  6076. Is your °dONLNd Δ\“∂)%Kapplication at least “conscious” of the fact that it may be in a multi-user°dONLNdW“7fi3(˙U2environment? For instance, does it work correctly °dONLNdâ“3fi∂)¸if a volume containing an°dONLNd£fi7Í(U.existing document is on a locked volume? Does °dONLNd—fiÍ∂)„"it check all result codes returned°dONLNdÙÎ7˜≈(Ufrom File Manager  calls, and °dONLNdÍ≈ˆ˝)éResError°dONLNdν˜µ)8' after relevant Resource Manager calls?°dONLNdB™(+6EOK, I follow the rules. What do I do to make my application sharable?°dONLNdà'j*There is a flag in °dONLNdõj'⁄)RNeach file’s Finder information (stored in the file’s directory entry) known as°dONLNdÍ'3ª(O6[the “shared” bit. If you set this bit on your application’s resource file, the Finder will °dONLNdE'ª3⁄(OŸlaunch°dONLNdL3?Û([6.your application using read-only permissions; °dONLNdz3Û?⁄)€1if anyone else launches your application, they’ll°dONLNd¨?K](g6Ialso get it read-only (their Finder will see the same “shared” bit set.).°dONLNdˆWc*4Three important warnings accompany this information:°dONLNd+o*{.+•°dONLNd-o7{Ñ)
  6077. The definition °dONLNd<oÑ{∂)M9of the “shared” bit was incorrect in previous releases of°dONLNdv{7áì(£UEinformation and software from Apple. This includes the June 16, 1986 °dONLNdª{ìá∂(£±version°dONLNd√á7ìÀ(ØUof M.TB.Finder Flags (fixed °dONLNdfláÀì∂)î-in the March 2, 1987 version), as well as all°dONLNd
  6078. ì7üb(ªU    versions °dONLNdìbü∂)+Bof ResEdit before and including 1.1b3 (included with MPW 2.0). For°dONLNdYü7´÷(«U"now, the most reliable way to set °dONLNd{ü÷´∂)ü0this bit is to get the 1.1b3 version of ResEdit,°dONLNd¨´7∑_(”U
  6079. use it to °dONLNd∂´_∑∂)(FGet Info on your application, and check the  box labeled “cached” (the°dONLNd˝∑7√(flU+incorrect documentation upon which ResEdit °dONLNd(∑√∂)‹"et al.] was based  called the real°dONLNdK√7œ (ÎU4shared bit “cached”; the bit labeled as “shared” is °dONLNd√ œ∂)È!the real cached bit [a  currently°dONLNd°œ7€-(˜U5unused but reserved bit which should be left clear]).°dONLNd◊Á*Û.(H•°dONLNdŸÁ7Ûæ)
  6080. By checking this bit, you’re °dONLNdˆÁæÛ∂)á4promising (to your users) that your application will°dONLNd    +Û7ˇy(Uwork entirely °dONLNd    9Ûyˇ∂)B@correctly if launched by more than one user. This means that you°dONLNd    zˇ7 Z('Ufollow °dONLNd    ÅˇZ ∂)#Hthe other rules, in addition to simply not writing to your application’s°dONLNd      7-(3U1own resource file. See  “Application Development °dONLNd    ˚ -∂)ˆfor a Shared Environment,”°dONLNd
  6081. 7#ã(?Uand test carefully!°dONLNd
  6082. */*;.(WH•°dONLNd
  6083. ,/7;ë)
  6084. Setting this bit has °dONLNd
  6085. A/ë;∂)Z;nothing to do with allowing your application’s documents to°dONLNd
  6086. };7G
  6087. (cU.be shared;  you must design this feature into °dONLNd
  6088. ´;
  6089. G∂)”$your application (it’s not something°dONLNd
  6090. –G7S(oU*that Apple system  software can take care °dONLNd
  6091. ˙GS∂)Õ$of behind your application’s back.).°dONLNd S7_({U,You should realize from reading  this note, °dONLNd KS_∂)›however, that if you store your°dONLNd k_7kì(áUdocument’s data in °dONLNd ~_ìk∂)\=resource files, you won’t be  able to allow multiple users to°dONLNd ºk7wΩ(ìUaccess them simultaneously. ¡4¡˘
  6092. (÷62) of 3)µ=NW 12 - AppleShare-able Applications and the Resource Manager+ñM.NW.AppleShareableAppsˇX◊#ˇ ˇˇˇˇ#◊ 
  6093. IR,Times
  6094. .+Z-Developer Support Center(-Ï
  6095. March 1988 /X/
  6096. °dONLNd)<5¶(QZFurther Reference: TXT°dONLNd6NBR+
  6097. •°dONLNd6`BÕ)The Resource Manager°dONLNd*BNNR(jl•°dONLNd,B`NY)1“Application Development in a Shared Environment”°dONLNd^NNZR(vl•°dONLNd`N`ZΩ)M.TB.Finder Flags ¡X¡
  6098. (÷Z=NW 12 - AppleShare-able Applications and the Resource Manager(÷3) of 3(ÏZM.NW.AppleShareableAppsˇ ◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  6099. /ZÅ#
  6100.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  6101. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  6102. .WIQkWIQk+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  6103. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  6104. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  6105.     l+&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  6106. BÄ(Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É°dWORD†ç
  6107. IR.°dONLNdo<Çú(úZ(NW 13 - AppleTalk: The Rest of the Story
  6108. °dONLNd)Å<êä*
  6109. Networking
  6110. °dONLNd5ú<®v* Updated by:°dONLNdAúÑ®
  6111. )HRich Kubota and Jim Luther°dONLNd\úæ®˛(ƒ‹ January 1993°dONLNdi®<¥q(–Z Written by:°dONLNdu®Ñ¥)HRich Kubota and Scott Kuechle°dONLNdì®∏¥˛(–÷
  6112. February 1992°dONLNd°¿<Ã√(ËZRThis Technical Note discusses the updates and modifications to a number of facets °dONLNdÛ¿√Ã˛(Ë· of the lower°dONLNdÃ<ÿ((ÙZ1levels of AppleTalk Phase 2 since the release of °dONLNd1Ã(ÿ{)ÏInside Macintosh°dONLNdAÃ{ÿ˛)S Volume VI. Topics range°dONLNdZÿ<‰≠(Zfrom discussion of the °dONLNdqÿ≠‰˛)qAnew Datagram Delivery Protocol (DDP) layer calls to the AppleTalk°dONLNd≥‰<t( ZBMultiple Node Architecture to a discussion at the driver level of °dONLNdı‰t˛( íthe new Multivendor ADEV°dONLNd<¸§(ZArchitecture. Most of °dONLNd$§¸˛)hEthe information presented here concerns AppleTalk versions 56 through°dONLNdj¸<N($Z58; °dONLNdn¸N˛)\however, additional material is presented to clarify and correct material presented in other°dONLNdÀ<e(0Z>AppleTalk documentation relating to all versions of AppleTalk.°dONLNd
  6113.  <,≥*LReordered subjects according to the order of the AppleTalk version in which °dONLNdV ≥,˛(H—the feature was°dONLNdf,<8ô(TZfirst implemented. °dONLNdy,ô8˛)]EAdded a table of contents to make it easier to find material. Added a°dONLNdø8<D«(`ZNdiscussion on Multivendor ADEV Architecture, the .TOKN driver interface, plus °dONLNd
  6114. 8«D˛(` information°dONLNdD<P€(lZQon making AppleTalk drivers compatible with virtual memory under system software °dONLNdjD€P˛(l˘version°dONLNdrP<\’(xZ7.0.x. Added a description of °dONLNdêP’\˛)ô8the change to the .ENET interface presented by the Apple°dONLNd…\<h¨(ÑZSONIC-based Ethernet °dONLNdfi\¨h˛)pCdrivers. Added socket listener sample code. Added AppleTalk version°dONLNd"h<tN(êZlist.°dONLNd(Ä<åÛ*Changes since September 1992:°dONLNdEÄÛåù)∑" Corrected the .TOKN interface to °dONLNdgÄùå˛)™remove reference to°dONLNd{å<ò5(¥Z5the A1 register on packet reception. Described a bug °dONLNd∞å5ò˛)˘ with the LAPAddATQ and LAPRmvATQ°dONLNd—ò<§–(¿ZVglue code that exists in the MPW Interface.o library file, and published an Assembler °dONLNd'ò–§˛(¿Ó    glue code°dONLNd1§<∞∞(ÃZfile to work around the °dONLNdI§∞∞˛)tAproblem. Described a change to the .ENET EGetInfo call interface.°dONLNdã∞<ºŸ(ÿZQDescribed a change to the 'atlk' AGetInfo call required of ADEVs to support SNMP °dONLNd‹∞Ÿº˛(ÿ˜(Simple°dONLNd‰º<»j(‰ZNetwork °dONLNdϺj»˛).JManagement Protocol). Discussed other changes required for .TOKN and .ENET°dONLNd7»<‘¸(Z%support of SNMP. Provided additional °dONLNd\»¸‘˛)¿3clarification to the LAP Manager calls, LRdDispatch°dONLNdê‘<‡Ú(¸ZYand LWrtInsert. Presented a correction to the ENET.h header file supplied with MPW 3.2.x.  X 
  6115. °dONLNdÍÙ`ê+$  Introduction°dONLNd¯Ù×(Í2°dONLNd˚ˇÑ O('¢0Where Can I Get the Latest Version of AppleTalk?°dONLNd,ˇÃ —('Í3°dONLNd.
  6116. `…(2~The 'atkv' Gestalt Selector°dONLNdJ
  6117. ×(2Í4°dONLNdL`!ø(=~Sample Socket Listener°dONLNdcÃ!—(=Í4°dONLNdf Ñ,„(H¢Socket Listener Review°dONLNd} Ã,—(HÍ5°dONLNdÄ+Ñ7(S¢#Timing Considerations for LocalTalk°dONLNd§+Ã7—(SÍ5°dONLNdß6ÑB¿(^¢Register Usage°dONLNd∂6ÃB—(^Í5°dONLNdπAÑMÎ(i¢Socket Listener Overview°dONLNd“AÃM—(iÍ6°dONLNd’LÑX(t¢Socket Listener Assembler Code°dONLNdÙLÃX—(tÍ7°dONLNd˜WÑc(¢ Initializing the Socket Listener°dONLNd    W«c—(Â12°dONLNd    bÑnÏ(ä¢Using the Socket Listener°dONLNd    6b«n—(äÂ14°dONLNd    9m`y‰(ï~The AppleTalk Transition Queue°dONLNd    Xm«y—(ïÂ15°dONLNd    \xÑÑ](†¢*Bug with LAPAddATQ and LAPRmvATQ Glue Code°dONLNd    áx«Ñ—(†Â16°dONLNd    ãÉÑè&(´¢&Calling the AppleTalk Transition Queue°dONLNd    ≤É«è—(´Â18 ¡X¡(÷Z(NW 13 - AppleTalk: The Rest of the Story(÷ˇ1) of 61(ÏZM.NW.AppleTalk2ˇ°¿Ù%%DSIDICT:_cv
  6118. currentdict /bu known {bu}if
  6119. userdict /_cv known not{userdict /_cv 30 dict put}if
  6120. _cv begin
  6121. /bdf{bind def}bind def
  6122. currentscreen/cs exch def/ca exch def/cf exch def
  6123. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  6124. /ss{//cf //ca //cs setscreen}bdf
  6125. /stg{ss setgray}bdf
  6126. /strgb{ss setrgbcolor}bdf
  6127. /stcmyk{ss cvcmyk}bdf
  6128. /min1{dup 0 eq{pop 1}if}bdf
  6129. end
  6130. currentdict /bn known {bn}if
  6131. †ø‘◊#ˇ ˇˇˇˇ#◊ 
  6132. IR,Times
  6133. .+6-Macintosh Technical Notes /4/˘°dONLNd`)+H'Standard AppleTalk Transition Constants°dONLNd(£)≠(E¡18°dONLNd,(`4ÿ(P~The Flagship Naming Service°dONLNdH(£4≠(P¡19°dONLNdM3Ñ?=([¢'The ATTransNameChangeAskTask Transition°dONLNdu3£?≠([¡19°dONLNdz>ÑJ=(f¢(The ATTransNameChangeTellTask Transition°dONLNd£>£J≠(f¡20°dONLNd®IÑU5(q¢&The ATTransCancelNameChange Transition°dONLNdœI£U≠(q¡20°dONLNd‘TÑ`û(|¢CSystem 7.0 Sharing Setup cdev / Flagship Naming Service Interaction°dONLNdT£`≠(|¡21°dONLNd_`k5(á~0AppleTalk Remote Access Network Transition Event°dONLNdM_£k≠(á¡21°dONLNdRjÑv0(í¢'The ATTransNetworkTransition Transition°dONLNdzj£v≠(í¡21°dONLNduÑÅg(ù¢4Network Transition Event for AppleTalk Remote Access°dONLNd¥u£Å≠(ù¡21°dONLNd∏Ä`å˙(®~#Cable Range Change Transition Event°dONLNd‹Ä£å≠(®¡22°dONLNd·ãÑó(≥¢!The ATTransCableChange Transition°dONLNdã£ó≠(≥¡23°dONLNdñ`¢(æ~!The Speed Change Transition Event°dONLNd)ñ£¢≠(æ¡23°dONLNd.°Ñ≠(…¢!The ATTransSpeedChange Transition°dONLNdP°£≠≠(…¡24°dONLNdT¨`∏*(‘~-Sample Pascal Source to LAPMgrExists Function°dONLNdǨ£∏≠(‘¡24°dONLNdÜ∑`√(fl~*Sample AppleTalk Transition Queue Function°dONLNd±∑£√≠(fl¡25°dONLNd∂¬ÑŒS(Í¢/Sample AppleTalk Transition Queue Function in C°dONLNdʬ£Œ≠(Í¡25°dONLNdÎÕÑŸe(ı¢4Sample AppleTalk Transition Queue Function in Pascal°dONLNd Õ£Ÿ≠(ı¡29°dONLNd#ÿ<‰æ(ZMultivendor ADEV Architecture°dONLNdAÿ£‰≠(¡36°dONLNdE„`Ô≥( ~Original Limitations°dONLNdZ„£Ô≠( ¡36°dONLNd^Ó`˙≤(~.TOKN Driver Shell°dONLNdqÓ£˙≠(¡37°dONLNdu˘`∂(!~.TOKN Driver Basics°dONLNdâ˘£≠(!¡37°dONLNdå<Â(,Z(Driver Considerations for Virtual Memory°dONLNdµ£≠(,¡38°dONLNdπ`—(7~Limiting DeferUserFn Calls°dONLNd‘£≠(7¡39°dONLNdÿ`&Õ(B~Implementing DeferUserFn°dONLNdÒ£&≠(B¡40°dONLNdÙ%<1(MZ5SONIC-Based Ethernet Driver Software Interface Change°dONLNd*%£1≠(M¡40°dONLNd.0`<©(X~EGetInfo Changes°dONLNd?0£<≠(X¡40°dONLNdC;`GA(c~3Distinguishing Apple’s SONIC-Based Ethernet Systems°dONLNdw;£G≠(c¡41°dONLNdzF<R‘(nZ$Correction to the ENET.h Header File°dONLNdüF£R≠(n¡42°dONLNd¢Q<]÷(yZ$AppleTalk Multiple Node Architecture°dONLNd«Q£]≠(y¡42°dONLNdÀ\`hå(Ñ~ What Is It?°dONLNd◊\£h≠(Ñ¡43°dONLNd€g`s(è~%Glue Code For Multinode Control Calls°dONLNdg£s≠(è¡43°dONLNdr`~m(ö~<Things You Need to Know When Writing a Multinode Application°dONLNdBr£~≠(ö¡45°dONLNdG}Ñâ‡(•¢AddNode (csCode=262)°dONLNd\}£â≠(•¡46°dONLNdaàÑîÚ(∞¢RemoveNode (csCode=263)°dONLNdyà£î≠(∞¡47°dONLNd~ìÑüÕ(ª¢Receiving Packets°dONLNdêì£ü≠(ª¡47°dONLNdîû`™(Δ~$Sending Datagrams Through Multinodes°dONLNdπû£™≠(Δ¡48°dONLNdæ©Ñµ·(—¢NetWrite (csCode=261)°dONLNd‘©£µ≠(—¡48°dONLNdÿ¥`¿C(‹~0AppleTalk Remote Access Network Number Remapping°dONLNd    ¥£¿≠(‹¡49°dONLNd
  6134. ø`ÀÍ(Á~!Is There a Router on the Network?°dONLNd/ø£À≠(Á¡49°dONLNd2 <÷´(ÚZNew for AppleTalk ADEVs°dONLNdJ £÷≠(Ú¡49°dONLNdN’`·§(˝~AGetInfo (D0=3)°dONLNd^’£·≠(˝¡50°dONLNdb‡`Ï©(~AAddNode (D0=9)°dONLNdr‡£Ï≠(¡51°dONLNdvÎ`˜∞(~ADelNode  (D0=10)°dONLNdàΣ˜≠(¡52°dONLNdåˆ`æ(~AGetNodeRef  (D0=11)°dONLNd°ˆ£≠(¡53°dONLNd•`
  6135. û()~
  6136. AOpen  (D0=7)°dONLNd≥£
  6137. ≠()¡53°dONLNd∑ `ù(4~
  6138. AClose (D0=8)°dONLNd≈ £≠(4¡54°dONLNd…`#ü(?~AInstall (D0=1)°dONLNdŸ£#≠(?¡54°dONLNd›"`.±(J~AShutDown (D0=2)°dONLNdÓ"£.≠(J¡54°dONLNdÚ-`9©(U~Receiving Packets°dONLNd-£9≠(U¡54°dONLNd8`D›(`~Defending Multinode Addresses°dONLNd&8£D≠(`¡55°dONLNd)C<O¯(kZ-Corrections/Clarifications to the LAP Manager°dONLNdWC£O≠(k¡55°dONLNd[N`Zª(v~LRdDispatch (DO = 1)°dONLNdpN£Z≠(v¡55°dONLNdtY`e≤(Å~LWrtInsert (DO = 2)°dONLNdàY£e≠(Å¡55°dONLNdãd<p∫(åZAppleTalk Version Information°dONLNd©d£p≠(å¡56°dONLNd¨o<{”(óZ#Contacting Apple Software Licensing°dONLNd–o£{≠(ó¡57 †4†˘ ¡4¡˘(÷62) of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇh◊#ˇ ˇˇˇˇ#◊ 
  6139. IR,Times
  6140. .+Z-Developer Support Center(-Á January 1993 /X/
  6141. °dONLNd)<<°(VZ Introduction
  6142. °dONLNd
  6143. G<SÏ*YThis Tech Note differs from previous revisions in that the subjects have been reordered. °dONLNdfGÏS˛(o
  6144. The°dONLNdjS<_l({Z topics are °dONLNduSl_˛)0Rpresented according to the order of the AppleTalk version in which the feature was°dONLNd»_<kÇ(áZEfirst implemented. You can find new topics and modifications to this °dONLNd
  6145. _Çk˛(á†Tech Note by looking for°dONLNd&k<w(ìZ/material set off by change bars in the margins.°dONLNdVÉ<è*,The first section in this Note, “The 'atkv' °dONLNdÇÉè˛)Δ5Gestalt Selector,” discusses the new Gestalt selector°dONLNd∏è<õî(∑ZG'atkv', which provides version information when AppleTalk is available.°dONLNdß<≥•*EThe next section, “Sample Socket Listener,” presents a sample socket °dONLNdFß•≥˛(œ√listener, including°dONLNdZ≥<øß(€ZLinitialization code to assist high-level language programmers. There socket °dONLNd¶≥ßø˛(€≈listener comments°dONLNd∏ø<À•(ÁZQdescribe in detail the basic functions of packet handling at the data link layer.°dONLNd
  6146. ◊<„Œ*LThe next section, “The AppleTalk Transition Queue,” discusses the AppleTalk °dONLNdV◊Œ„˛(ˇÏ
  6147. Transition°dONLNda„<Ô¡( ZQueue including its support °dONLNd}„¡Ô˛)Ö=for the Flagship Naming Service, AppleTalk Remote Access, and°dONLNdªÔ<˚(Z+changes to processor speed that can affect °dONLNdÊÔ˚˛)›*LocalTalk and other processes dependent on°dONLNd˚<o(#Z
  6148. processor °dONLNd˚o˛)3Jspeed. Included is Pascal source code for checking whether the Phase 2 LAP°dONLNdf<É(/Z?Manager exists to support the Transition Queue mechanism, plus °dONLNd•ɲ(/°sample Transition Queue°dONLNdΩ<Œ(;Zhandlers written in both C and °dONLNd‹Œ˛)í?Pascal. This section includes a description of an important bug°dONLNd<+§(GZ@that exists in the glue code, implemented for the LAPAddATQ and °dONLNd\§+˛(G¬
  6149. the LAPRmvATQ°dONLNdj+<7™(SZGfunctions. The glue code is from the MPW Interface.o file. Replacement °dONLNd±+™7˛(S»glue routines are°dONLNd√7<CÆ(_ZGprovided to work around the problem for both MPW and Think programmers.°dONLNd O<[*,The section “Multivendor ADEV Architecture” °dONLNd7O[˛)„+presents the Multivendor ADEV Architecture,°dONLNdc[<g?(ÉZ4which allows for Ethernet and token ring cards from °dONLNdó[?g˛(É]'multiple vendors to be installed on the°dONLNdøg<sÜ(èZGsame system. Included is a description of the functionality of the new °dONLNdgÜs˛(è§driver shells for Ethernet°dONLNd!s<÷(õZUand token ring, plus a description of the .TOKN interface required for compatibility °dONLNdvs÷˛(õÙwith the°dONLNd<ã≤(ßZnew ADEV Architecture.°dONLNdñó<£É*AThe section “Driver Considerations for Virtual Memory” shows how °dONLNd◊óÉ£˛(ø°to modify driver code for°dONLNdÒ£<Øi(ÀZ>compatibility with system software version 7.0 virtual memory.
  6150. °dONLNd0ª< º*SONIC-Based Ethernet Driver Software Interface Change
  6151. °dONLNdf÷<‚œ*OThe section “SONIC-Based Ethernet Driver Software Interface Change” presents a °dONLNdµ÷œ‚˛(˛Ì    change to°dONLNdø‚<Óµ(
  6152. Zthe .ENET interface that °dONLNdÿ‚µÓ˛)y?resulted from the implementation of the SONIC Network Interface°dONLNd    Ó<˙(Z*Controller on the Ethernet NB Card and in °dONLNd    BÓ˙˛)À2the Macintosh Quadra computer’s built-in Ethernet.°dONLNd    u˙<«("ZPThe change concerns the EGetInfo function, which now returns additional network °dONLNd    ≈˙«˛(" information°dONLNd    —<?(.Z4for Apple Ethernet products based on the SONIC chip.°dONLNd
  6153. <*h*>The section “Correction to the ENET.h Header File” presents a °dONLNd
  6154. Dh*˛(FÜ!correction to the header file for°dONLNd
  6155. f*<6t(RZ>programs that will make a parameter block Control call to the °dONLNd
  6156. §*t6˛(Rí.ENET, .TOKN, or .FDDI°dONLNd
  6157. ª6<Bå(^Zdriver, to add or °dONLNd
  6158. Õ6åB˛)PLdelete multicast addresses. This problem applies only to C programs that are°dONLNd B<Nó(jZwritten to include °dONLNd -BóN˛)[@the ENET.h file supplied with MPW version 3.2.x and with Think C°dONLNd nN<Z§(vZversions 5.0 to 5.0.4.°dONLNd Öf<r√*MThe section “AppleTalk Multiple Node Architecture” discusses the new program °dONLNd “f√r˛(é·
  6159. interfaces to°dONLNd ‡r<~ï(öZCthe AppleTalk Multiple Node Architecture. The new architecture was °dONLNd #rï~˛(ö≥developed to support°dONLNd 8~<ä‘(¶Z multiple node capability on the °dONLNd X~‘ä˛)ò9Macintosh computer, which allows the Macintosh to present°dONLNd íä<ñ|(≤ZAitself as separate entities, or unique nodes on the network. The °dONLNd ”ä|ñ˛(≤öAppleTalk Remote Access ¡X¡
  6160. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷ˇ3) of 61(ÏZM.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  6161. IR,Times
  6162. .+6-Macintosh Technical Notes /4/˘
  6163. °dONLNd)2*6program uses multinode capability to implement Remote °dONLNd62)⁄(EP"Access functionality. This section°dONLNdY)5è(Q6presents the Datagram °dONLNdo)è5⁄)w=Delivery Protocol (DDP) interface for multinode AppleTalk for°dONLNd≠5A!(]6:applications to take advantage of this new functionality. °dONLNdÁ5!A⁄(]?$This Note, however, does not discuss°dONLNd AM†(i6the Remote Access program.°dONLNd'Ye4*3The section “New for AppleTalk ADEVs” presents the °dONLNdZY4e⁄(ÅRchanges required of an ADEV’s,
  6164. Courier°dONLNdxeqB(é6'atlk'°dONLNd~fBr7)*4 code resource for compatibility with the AppleTalk °dONLNd≤f7r⁄)ı Multinode Architecture. While we°dONLNd”r~j(ö6recommend that °dONLNd‚rj~⁄)REdevelopers of Ethernet and token ring network hardware conform to the°dONLNd(~ä3(¶6:specifications of the Multivendor ADEV Architecture, this °dONLNdb~3ä⁄(¶Q"information is presented for those°dONLNdÖäñÄ(≤6Gdevelopers of network products for which Apple does not supply an ADEV.°dONLNdÕ¢ÆA*>The final section, “AppleTalk Version Information,” lists the °dONLNd ¢AÆ⁄( _various versions of AppleTalk,°dONLNd*Æ∫i(÷6Gand the new products that require the support of the AppleTalk version.
  6165. °dONLNdr“·k*'0Where Can I Get the Latest Version of AppleTalk?
  6166. °dONLNd£Ì˘Ä*KFor testing purposes, the latest version of AppleTalk and related software °dONLNdÓÌĢ⁄(ûis available on the°dONLNd˘3(!6latest °dONLNd    ˘3v) Developer CD°dONLNd˘vy)C °dONLNd˘yñ)Series°dONLNd˘ñ≥) disc, °dONLNd#˘≥⁄):on AppleLink on the Developer Services Bulletin Board, and°dONLNd^_(-6on the Internet °dONLNdn_⁄)GKthrough anonymous FTP to ftp.apple.com (130.43.2.3). It can be installed by°dONLNd∫À(96%using the Network Software Installer.
  6167. °dONLNd‡5D *'The 'atkv' Gestalt Selector
  6168. °dONLNd¸Q]-*The °dONLNdP-\W)'atkv'°dONLNdQW]¬)*N Gestalt selector is available beginning with AppleTalk version 56 to provide °dONLNdTQ¬]⁄(y‡more°dONLNdY]iÆ(Ö6complete version information °dONLNdv]Æi⁄)ñ:regarding AppleTalk, and as an alternative to the existing°dONLNd±iuB(í6'atlk'°dONLNd∑jBv»)* Gestalt selector. Beginning °dONLNd‘j»vc)Üwith AppleTalk version 54, the °dONLNdÛicuç)õ'atlk'°dONLNd˘jçv⁄)* Gestalt selector°dONLNd wÉ!(ü68was available to provide basic version information. The °dONLNdCv!ÇK(ü?'atlk'°dONLNdIwKÉÄ)*
  6169.  selector is °dONLNdVwÄÉ⁄)5not available when°dONLNdiÉè(´68AppleTalk is turned off in the Chooser. It is important °dONLNd°Éè⁄(´8(to note that the information between the°dONLNd êú.(∏6two °dONLNdŒê.úá)Fresources is provided in a different manner. Calling Gestalt with the °dONLNdèáõ±(∏•'atlk'°dONLNdê±ú⁄)*     selector°dONLNd$ú®!(ƒ67provides the major revision version information in the °dONLNd[ú!®⁄(ƒ?&low-order byte of the function result.°dONLNdÇ©µä(—6Calling Gestalt with the °dONLNdõ®ä¥¥)r'atkv'°dONLNd°©¥µ)* selector provides the °dONLNd∏©µ⁄)g'version information in a manner similar°dONLNd‡∂¬5(fi6to the °dONLNdÁµ5¡_)'vers'°dONLNdÌ∂_¬Ê)* resource. The format of the °dONLNd
  6170. µÊ¡)áLONGINT°dONLNd∂¬v)1 result is as follows:
  6171.     °dONLNd)Œ<ŸU(ıZbyte;°dONLNd4ŒŸx)ÿ/* Major revision */°dONLNdJÿ<„U(ˇZbyte;°dONLNdUÿ„x)ÿ/* Minor revision */°dONLNdk‚<ÌP(    Zbyte°dONLNdq‚ÑÌ„)Hdevelopment = 0x20,°dONLNdÜ‚Ìx)ê/* Release stage  */°dONLNdûÏј≈(¢
  6172. alpha = 0x40,°dONLNd؈ѿ*
  6173. beta = 0x60,°dONLNdøÑ B*
  6174. &final = 0x80, /* or */ release = 0x80;°dONLNdÁ
  6175. <U(1Zbyte;°dONLNdÚ
  6176. å)ÿ/* Nonfinal release # */
  6177. °dONLNd     !-í(I6For example, passing the °dONLNd    $ í,º)z'atkv'°dONLNd    *!º-ø)* °dONLNd    +!ø-⁄);selector in a Gestalt call under AppleTalk version 57 gives°dONLNd    g.:Z(V6the following °dONLNd    u-Z9ã)BLONGINT°dONLNd    |.ã:Æ)1     result: °dONLNd    Ö-Æ9Ù)#
  6178. 0x39008000°dONLNd    è.Ù:¯)F.°dONLNd    ëFR;(n6Note: °dONLNd    óF;Ri)#?With the release of the System 7 Tuner product, AppleTalk will °dONLNd    ÷FiR∂(nánot be loaded at°dONLNd    ÁR<^‹(zZ"startup, if prior to the previous °dONLNd
  6179.     R‹^∂)†(shutdown AppleTalk was turned off in the°dONLNd
  6180. 2_<k‰(áZ"Chooser. Under this circumstance, °dONLNd
  6181. T_‰kÚ)®the
  6182. °dONLNd
  6183. W_Úkˆ) 
  6184. °dONLNd
  6185. X^ˆj )'atkv'
  6186. °dONLNd
  6187. ^_ k$)* 
  6188. °dONLNd
  6189. __$k∂)!selector is not available. If the°dONLNd
  6190. Åk<wf(îZ'atkv'°dONLNd
  6191. álfxî)*
  6192.  selector °dONLNd
  6193. ëlîx∂).:is not available under System 7, this is an indicator that°dONLNd
  6194. Ãx<Ñí(†ZAppleTalk cannot °dONLNd
  6195. ›xíÑ∂)V:be turned on without doing so in the Chooser and rebooting°dONLNd Ñ<êr(¨Z the system. ¡4¡˘
  6196. (÷64) of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇƒ◊#ˇ ˇˇˇˇ#◊ 
  6197. IR,Times
  6198. .+Z-Developer Support Center(-Á January 1993 /X/
  6199. °dONLNd5<D◊(`ZSample Socket Listener
  6200. °dONLNdP<\*+The preferred AppleTalk calls presented in °dONLNdBP\f)◊Inside Macintosh°dONLNdRPf\¡)S Volume V, page °dONLNdbP¡\˛)[ 513, do not°dONLNdn]<i‘(ÖZ#include a preferred style call for ,
  6201. Courier°dONLNdë\‘h)òDDPRead°dONLNdò]i˛)14. As a result developers are faced with the prospect°dONLNdÕj<vå(íZof writing their °dONLNdfijåv()Psocket listeners and using the °dONLNd˝i(u`)úPOpenSkt°dONLNdj`v˛)8 function when upgrading their°dONLNd$v<Çs(ûZ
  6202. programs. °dONLNd.vsÇ«)7Inside Macintosh°dONLNd>v«ÇÄ)T" Volume II, page 324, presents an °dONLNd`vÄDz)πoverview of how socket°dONLNdwÇ<éΩ(™Zlisteners should function. °dONLNdíÇΩé)ÅInside Macintosh°dONLNd¢Çéù)S states that socket listeners, °dONLNd¡Çùé˛)ças well as protocol°dONLNd’é<ö«(∂Zhandlers, need to be written °dONLNdÚé«ö˛)ã>in assembly code, since parameters are passed in registers. To°dONLNd1ö<¶Â(¬Z#assist high-level programmers with °dONLNdTö¶˛)©<implementing a socket listener, the generic listener code is°dONLNdë¶<≤Ç(ŒZBprovided. The following code demonstrates how to do the following:°dONLNd‘æN R+•°dONLNd÷æW √)    buffer multiple packets°dONLNdÓ÷N‚R(˛l•°dONLNd÷W‚)    "return DDP/LAP header information °dONLNd÷‚Ï)Æ/that has already been read into the Read Header°dONLNdB‚WÓ∫(
  6203. uArea (RHA) by DDP°dONLNdT˙NR("l•°dONLNdV˙WÇ)    
  6204. calculate °dONLNd`˙ÇÏ)+Eand compare the packet checksum when a packet uses a long DDP header,°dONLNd¶WÒ(.uand includes the checksum value°dONLNdΔ<*ò(FZSome of the things °dONLNdŸò*˛)\Hthat the listener sample does not do, which you might wish to implement,°dONLNd"*<6è(RZare the following:°dONLNd5BNNR+•°dONLNd7BWNŒ)    Check the DDP type and °dONLNdNBŒNÏ)w<ignore any packets that don’t match the desired type(s) that°dONLNdãNWZ∂(vuyou’re interested in.°dONLNd°fNrR(él•°dONLNd£fWrõ)    @Check the source node ID and ignore any packets that don’t come °dONLNd„fõrÏ(éπfrom the desired°dONLNdÙrW~(öunode(s).°dONLNd˝äNñR(≤l•°dONLNdˇäWñó)    AIf the socket listener is used by more than one socket, it could °dONLNd@äóñÏ(≤µroute the packets°dONLNdRñW¢N(æu3differently based on the socket number found in D0.°dONLNdÜÆN∫R(÷l•°dONLNdàÆW∫≤)    The socket listener °dONLNdúÆ≤∫Ï)[@does not handle the implementation of a completion routine to be°dONLNd›∫WΔ(‚u&executed when the packet is processed.°dONLNd“<fiı(˙Z\The example listener code includes an initialization routine which the listener client uses °dONLNd`“ıfi˛(˙to°dONLNdcfi<Í™(Znotify the listener code °dONLNd|fi™Í˛)nFof the “available” and “used” buffer queues. A high-level procedure is°dONLNd√Í<ˆ‚(Z_provided to demonstrate the initialization of the listener, and the use of the socket listener.°dONLNd#<¬*Socket Listener Review°dONLNd:<&È*"The reader is advised to refer to °dONLNd\È&=)≠Inside Macintosh°dONLNdl=&‰)T Volume II, pages 324 to 330, °dONLNdä‰&˛)ßfor a°dONLNdê&<2R(NZ=description of protocol handlers, socket listeners, and data °dONLNdÕ&R2˛(Np"reception in the AppleTalk Manager°dONLNd2<>T(ZZover °dONLNdı2T>˛)VLocalTalk. The same architecture applies to AppleTalk on Ethernet and token ring. With°dONLNdL><J(fZ*the advent of AppleTalk Phase 2, the size °dONLNdv>J˛)Δ/of the Read Header Area (RHA) has been expanded°dONLNd¶J<VÒ(rZ#to accommodate the long DDP header.°dONLNd c<ox* After every °dONLNd÷bxnæ)<
  6205. ReadPacket°dONLNd‡cæo“)F or °dONLNd‰b“n)    ReadRest °dONLNdÌcoÅ)Acall, the listener code °dONLNd    cÅo˛)nmust check the Z (Zero)°dONLNd    p<|C(òZ8condition code for errors. If an error is detected from °dONLNd    UoC{â(òa
  6206. ReadPacket°dONLNd    _pâ|£)F, the °dONLNd    ep£|˛)code must not call°dONLNd    x|<à{(•Z    ReadRest. ¡X¡
  6207. *1(NW 13 - AppleTalk: The Rest of the Story(÷ˇ5) of 61(ÏZM.NW.AppleTalk2ˇ∞◊#ˇ ˇˇˇˇ#◊ 
  6208. IR,Times
  6209. .+6-Macintosh Technical Notes /4/˘
  6210. °dONLNd)D*
  6211. It is the °dONLNd
  6212. D)⁄),Presponsibility of the socket listener code to check for the existence of the DDP°dONLNd[)5±(Q6checksum. In contrast with the °dONLNdz)±5⁄)ô9Frame Check Sequence that the hardware uses to verify the°dONLNd¥5Ar(]6Bframe, the DDP checksum is implemented in extended DDP headers to °dONLNdˆ5rA⁄(]êverify that the packet°dONLNd
  6213. AMÁ(i6(data is not corrupted by memory or data °dONLNd5AÁM⁄)œ1bus errors within routers on the internet. If the°dONLNdgMY
  6214. (u64checksum has been entered, then the socket listener °dONLNdõM
  6215. Y⁄)ı*code must calculate the checksum after the°dONLNdΔYeß(Å6Qpacket has been read in, and compare the computed value with the passed checksum °dONLNdYße⁄(Å≈
  6216. value. The°dONLNd"eqƒ(ç6[sample listener code demonstrates this check and calculation of the checksum. The listener °dONLNd}eƒq⁄(ç‚code°dONLNdÇq}æ(ô6Xsets a flag that the program can check to determine whether the checksum matched or not.°dONLNd€âïª*YThe record structure presented in this sample returns the DDP type, destination node ID, °dONLNd4âªï⁄(±Ÿsource°dONLNd;ñ¢K(æ6 address in ,
  6217. Courier°dONLNdFïK°ä)3    AddrBlock°dONLNdOñä¢å)?: format, the hop count, the size of the packet, a flag to °dONLNdâñå¢⁄(æ™indicate whether°dONLNdö¢Ɖ( 6'a checksum error occurred, followed by °dONLNd¡¢‰Æ⁄)Ã0the actual datagram. The record structure can be°dONLNdÚÆ∫°(÷6extended to return additional °dONLNdư∫⁄)âBinformation, such as the tick count at the time the socket handler°dONLNdS∫ΔM(‚6 was called.°dONLNd`“fiÍ*#Timing Considerations for LocalTalk°dONLNdÑ͈ò*OIf LocalTalk is being used, your socket listener has less than 95 microseconds °dONLNd”Íòˆ⁄(∂(best case) to°dONLNd‚˜Ö(6read more data with a °dONLNd¯ˆÖÀ)m
  6218. ReadPacket°dONLNd˜À›)F or °dONLNdˆ›)ReadRest°dONLNd˜S)8 call. If you °dONLNd˜S⁄)>need more time, you might°dONLNd6·(+6*consider reading another 3 bytes into the °dONLNd`·⁄)…,RHA to buy another 95 microseconds. Remember°dONLNdç(763that the RHA may only have 8 bytes still available.°dONLNd¡'3n*Register Usage°dONLNd–?Km*LWhen the socket listener is called, the registers will be set up as follows:°dONLNdW3cZ+Register°dONLNd&WZcg)'(s)°dONLNd*W√cÌ)iContents°dONLNd4c<o\(ãZA0-A1°dONLNd:cÑo)HSCC addresses used by MPP°dONLNdUo<{J(óZA2°dONLNdYoÑ{)H Pointer to MPP’s local variables°dONLNd{{<áJ(£ZA3°dONLNd{Ñá)H Pointer to next free byte in RHA°dONLNd°á<ìJ(ØZA4°dONLNd•áÑìÆ)H9Pointer to ReadPacket {JSR (A4)} and ReadRest {JSR 2(A4)}°dONLNd‚ìÑüµ*
  6219. jump table°dONLNdÓü<´J(«ZD0°dONLNdÚüÑ´A)H'This packet’s destination socket number°dONLNd´<∑J(”ZD1°dONLNd´Ñ∑6)H&Number of bytes left to read in packet°dONLNdFœ*€1(˜H• °dONLNdIœ7€U)
  6220. ;Registers D0, D2, and D3 can be used freely throughout the °dONLNdÑœU€»(˜ssocket listener. A6, and°dONLNdù€7Áø(UD4 to D7 must be preserved.°dONLNdπÛ*ˇ1(H• °dONLNdºÛ7ˇ2)
  6221. 7From entry to socket listener until ReadRest is called:°dONLNdıˇ7 æ* The A5 register can be used.°dONLNd 7#* .Registers A0–A2, A4, and D1 must be preserved.°dONLNdB#*/.(KH•°dONLNdD#7/)
  6222. .From ReadRest until exit from socket listener:°dONLNdt/7;›* "The A5 register must be preserved.°dONLNdò;7G
  6223. * *Registers A0–A3 and D0–D3 are free to use.°dONLNd√S_.({6:You should assume only 8 bytes are still available in the °dONLNd˝S._⁄({LRHA for your use. The RHA will°dONLNd    _k†(á6contain one of the following: ¡4¡˘
  6224. *O6) of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ~◊#ˇ ˇˇˇˇ#◊ 
  6225. IR,Times
  6226. .+Z-Developer Support Center(-Á January 1993 /X/†Ç†å
  6227. <m ">Úx†å"JÚ "JjÙ†ç">Ú`"bÚx"ûÚx">j`°ñ °öˇ˝
  6228. KVK,
  6229. Courier
  6230.     .œõœõ°dONLNdˇˇ(S LLAP header†ó†å
  6231. <m "nÚ "njÙ†ç†å"zÚ "zjÙ†ç†å"ÜÚ "ÜjÙ†ç†å"íÚ "íjÙ†ç°ñ °öˇ¸
  6232. \vhÅ
  6233. °dONLNdˇˇ+cor†ó†å
  6234. <m "VÚ "VjÙ†ç°ñ °öˇ˝'
  6235. {ÜW
  6236.     °dONLNdˇˇ(ÉDDP short header†ó°ñ °öˇ¸5
  6237. >nJ⁄
  6238. °dONLNdˇˇ(GoTop of RHA (toRHA)†ó
  6239. <m ">éx†å"Jé "JÙ†ç >é˛é"béx"˛éx >˛°ñ °öˇ˝
  6240. KØVÁ
  6241.     °dONLNdˇˇ(S∞ LLAP header†ó†å
  6242. <m "né "nÙ†ç†å"zé "zÙ†ç†å"Üé "ÜÙ†ç†å"íé "íÙ†ç†å"Vé "VÙ†ç°ñ °öˇ˝$
  6243. {•ÜÒ°dONLNdˇˇ(ɶDDP long header†ó†å
  6244. <m "ûé "ûÙ†ç†å"™é "™Ù†ç†å"∂é "∂Ù†ç†å"¬é "¬Ù†ç†å"Œé "ŒÙ†ç†å"⁄é "⁄Ù†ç†å"Êé "ÊÙ†ç†å"Úé "ÚÙ†ç°d
  6245. MDPL    †åq@‰GÚDÚG‰D‰@‰DÚ"D⁄
  6246. †ç°dMDPL
  6247. °ñ °öˇ¸
  6248. û»™ÿ
  6249. °dONLNdˇˇ(ß…A3†ó°d
  6250. MDPL    †å
  6251. <m q†‰ßÚ§Ú߉§‰†‰§Ú"§⁄
  6252. †ç°dMDPL
  6253. °ñ °öˇ¸
  6254. ˛d
  6255. t°dONLNdˇˇ+ú`A3†ó°d
  6256. MDPL    †å
  6257. <m qÄééÄÄÄé"v
  6258. †ç°dMDPL
  6259. †ç†É
  6260. IR.°dONLNd<Œ(,ZSocket Listener Overview°dONLNd<(Ñ*BThe sample socket listener utilizes two standard operating system °dONLNd[Ñ(·(D¢(OS) queues (see °dONLNdl·(˛)]Inside°dONLNds(<4m(PZ    Macintosh°dONLNd|(m4¿)1 Volume II, page °dONLNdç(¿4˛)SF372), a free queue of available buffers that the listener uses to fill°dONLNd‘4<@°(\ZKwith incoming datagrams. The second linked list is a used queue of buffers °dONLNd4°@˛(\øthat the listener has°dONLNd5@<L-(hZ/processed, but that have not been processed by °dONLNdd@-L˛)Ò+the listener client. The SL_InitSktListener°dONLNdêL<XÜ(tZIroutine is called to pass the listener the pointers to the two OS queues.°dONLNd€d<p+*5When the listener is called to process a packet, the °dONLNdd+p˛)Ô-listener checks whether there is an available°dONLNd>q<}(ôZ1buffer record in the free queue by checking that °dONLNdop|A)‚qHead°dONLNdtqA}˛)#) element of the free queue is not nil. If°dONLNdû~<äõ(¶Zso, then the listener °dONLNd¥~õä2)_!sets register A3 to point to the °dONLNd’}2â)ó buffer_data°dONLNd‡~ä˛)M element of the record and°dONLNd˚ã<óg(≥Z
  6261. calls the °dONLNdägñü)+ReadRest°dONLNd
  6262. ãüó)8 routine. If there is no °dONLNd&ãó˛)p1available buffer record, the packet is ignored by°dONLNdXò<§_(¿Zcalling °dONLNd`ó_£ó)#ReadRest°dONLNdhòó§æ)8= with a buffer size value of 0. Maybe the next time a packet °dONLNd•òæ§˛(¿‹
  6263. is handled, a°dONLNd≥•<± (ÕZ-buffer will be available. If an error occurs °dONLNd‡• ±C)– during the °dONLNdΧC∞{)7ReadRest°dONLNdÛ•{±˛)8 function, then the listener°dONLNd±<ΩΩ(ŸZsimply returns to the caller.°dONLNd.…<’à*If the packet is °dONLNd?…à’˛)LLsuccessfully read, the listener processes the header information. The header°dONLNdå’<·‚(˝Z#information has been stored by the °dONLNdØ’‚·˛)¶:hardware driver in the MPP local variable space pointed to°dONLNdÍ·<ÌÚ(    Z(in register A2. The listener code fills °dONLNd·ÚÌ˛)∂6in the hop count field of the packet buffer record and°dONLNdIÌ<˘=(Z8determines the packet length. The listener then figures °dONLNdÅÌ=˘˛([)out whether it is dealing with a short or°dONLNd´˘<:(!Z6extended DDP header and fills in the remaining fields °dONLNd·˘:˛)˛(of the packet buffer. A check is made to°dONLNd
  6264. <¬(-ZSdetermine whether the checksum field of the DDP header is nonzero. If the field is °dONLNd]¬˛(-‡ nonzero, the°dONLNdj<£(:Zvalue is passed to the °dONLNdÅ£)g SL_DoChkSum°dONLNdåÙ)M °dONLNdçÙn)function to verify that the °dONLNd©n˛)zresulting checksum is zero. If°dONLNd»<+(GZ'the resulting checksum is nonzero, the °dONLNdÔ*o) buffer_CheckSum°dONLNd˛o+û)i
  6265.  field is °dONLNdû+¬)/set to °dONLNd¬*˙)$ckSumErr°dONLNd˙+˛)8,°dONLNd+<7_(TZ-3103°dONLNd,_8Á)# , otherwise the field is set to °dONLNd>+Á7
  6266. )ànoErr°dONLNdC,
  6267. 89)# . Finally, °dONLNdN,98q)/
  6268. the listener °dONLNd[+q7©)8Enqueues°dONLNdc,©8˛)8 the packet buffer°dONLNdv9<EÆ(aZinto the used queue and °dONLNdé8ÆDÊ)rDequeues°dONLNdñ9ÊE⁄)87 it from the free queue before returning to the caller.°dONLNdŒR<^ÿ(zZ!The calling program periodically °dONLNdÔRÿ^)ú checks the °dONLNd˙Q]1)6QHead°dONLNdˇR1^€)#! element of the used queue. When °dONLNd Q€]˛)™QHead°dONLNd&^<j5(ÜZ8is no longer nil, a packet is available for processing. °dONLNd^^5j˛)˘(The program processes the packet buffer.°dONLNdák<w[(ìZWhen °dONLNdåk[wÍ)finished, the packet buffer is °dONLNd´jÍv")èEnqueued°dONLNd≥k"wô)8 into the free queue and °dONLNdÃjôv—)wDequeued°dONLNd‘k—w˛)8     from the°dONLNdfiw<ɇ(üZused queue. The program might °dONLNd¸w‡É˛)§7then check for additional packets in the used queue and°dONLNd    4É<è‹(´Z process them in the same manner. ¡X¡
  6269. *+(NW 13 - AppleTalk: The Rest of the Story(÷ˇ7) of 61(ÏZM.NW.AppleTalk2ˇ§◊#ˇ ˇˇˇˇ#◊ 
  6270. IR,Times
  6271. .+6-Macintosh Technical Notes /4/˘
  6272. °dONLNd)5¢*$NThe program needs to define a sufficient number of packet buffers so that the °dONLNdN)¢5⁄(Q¿ listener has°dONLNd[5AY(]6Cbuffers available in the free queue between times when the program °dONLNdû5YA⁄(]wchecks the used queue and°dONLNd∏AMü(i6processes incoming packets.°dONLNd‘Ye–*Socket Listener Assembler Code,
  6273. Courier
  6274.     °dONLNdÛq|ä*J;_________________________________________________________________________°dONLNd>{Ü*
  6275. ;°dONLNd@Öêê*
  6276. ; Socket Listener Sample°dONLNdYèö*
  6277. ;°dONLNd[ô§©*
  6278. ; 3/92 Jim Luther,  Apple DTS°dONLNdy£Æ*
  6279. ;°dONLNd{≠∏¶*
  6280. ; ©1992 Apple Computer, Inc.°dONLNdò∑¬ä*
  6281. J;_________________________________________________________________________°dONLNd„À÷ü*    INCLUDE    'QuickEqu.a'°dONLNdˇ’‡ö*
  6282.     INCLUDE    'ToolEqu.a'°dONLNdflÍï*
  6283.     INCLUDE    'SysEqu.a'°dONLNd4ÈÙê*
  6284.     INCLUDE    'Traps.a'°dONLNdMÛ˛ü*
  6285.     INCLUDE    'ATalkEqu.a'°dONLNdi˝ï*
  6286.     INCLUDE    'SysErr.a'°dONLNdÉ*;°dONLNdÖ&*
  6287. ;°dONLNdá%0^*
  6288. ; Record Types°dONLNdñ/:*
  6289. ;°dONLNdò9Dä*
  6290. J;_________________________________________________________________________°dONLNd„MXΩ*!QHdr                  RECORD    0°dONLNdWbΩ*
  6291. !qFlags                DS.W      1°dONLNd'alΩ*
  6292. !qHead                 DS.L      1°dONLNdIkvΩ*
  6293. !qTail                 DS.L      1°dONLNdkuÄö*
  6294.                       ENDR°dONLNdÜâîΩ*!PacketBuffer          RECORD    0°dONLNd®ìûΩ*
  6295. !qLink                 DS.L      1°dONLNd ù®Ω*
  6296. !qType                 DS.W      1°dONLNdÏß≤+*
  6297. 7buffer_Type           DS.W      1            ; DDP Type°dONLNd$±ºS*
  6298. ?buffer_NodeID         DS.W      1            ; Destination node°dONLNddªΔ≠*
  6299. Qbuffer_Address        DS.L      1            ; Source address in AddrBlock format°dONLNd∂≈–0*
  6300. 8buffer_Hops           DS.W      1            ; Hop count°dONLNdÔœ⁄q*
  6301. Ebuffer_ActCount       DS.W      1            ; length of DDP datagram°dONLNd5Ÿ‰∑*
  6302. Sbuffer_CheckSum       DS.W      1            ; Chksum error returned here (cksumErr°dONLNdé„ÃÓ0+¥
  6303.          ; or noErr)°dONLNd£Ì¯S(6?buffer_Data           DS.B      ddpMaxData   ; the DDP datagram°dONLNd„˜ö*
  6304.                       ENDR°dONLNd˛ ä*J;_________________________________________________________________________°dONLNdI *
  6305. ;°dONLNdK*m*
  6306. ; Local Variables°dONLNd])4*
  6307. ;°dONLNd_3>ä*
  6308. J;_________________________________________________________________________°dONLNd™GRm*SL_Locals    PROC°dONLNdºQ\
  6309. *
  6310. 1        ENTRY free_queue,used_queue,current_qelem°dONLNdÓepî*Lfree_queue        DC.L    0        ; pointer to freeQ QHdr - initialized by °dONLNd?o®z+ê
  6311.       ; InitSktListener°dONLNdWyÑî(†6Lused_queue        DC.L    0        ; pointer to usedQ QHdr - initialized by °dONLNd®É®é+ê
  6312.       ; InitSktListener°dONLNd¬çòè(¥6Kcurrent_qelem     DC.L    0        ; pointer to current PacketBuffer record ¡4¡˘
  6313. *"8) of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ∂◊#ˇ ˇˇˇˇ#◊ 
  6314. IR,Times
  6315. .+Z-Developer Support Center(-Á January 1993 /X/,
  6316. Courier
  6317.     °dONLNd<(©(DZI                                   ; initialized by InitSktListener, then°dONLNdJ'<2«*
  6318. O                                   ; set by socket listener after every packet.°dONLNdö1<<ã*
  6319. C                                   ; NIL if no buffer is available.°dONLNdfi;<Fd*
  6320.     ENDP°dONLNdÁO<ZÆ*J;_________________________________________________________________________°dONLNd2Y<dA*
  6321. ;°dONLNd4c<nã*
  6322. C; SL_DoChksum - accumulate ongoing checksum (from Inside Macintosh)°dONLNdxm<xA*
  6323. ;°dONLNdzw<Çs*
  6324. ;    Input:°dONLNdÜÅ<å*
  6325. -;     D1 (word) = number of bytes to checksum°dONLNd¥ã<ñÊ*
  6326. ";     D3 (word) = current checksum°dONLNd◊ï<†*
  6327. (;     A1 points to the bytes to checksum°dONLNdü<™A*
  6328. ;°dONLNd©<¥x*
  6329. ;    Return:°dONLNd≥<æ†*
  6330. ;     D0 is modified°dONLNd$Ω<»˙*
  6331. &;     D3 (word) = accumulated checksum°dONLNdK«<“Æ*
  6332. J;_________________________________________________________________________°dONLNdñ€<Êõ*SL_DoChksum    PROC°dONLNd™Â<J*
  6333. 6    CLR.W      D0                    ; Clear high byte°dONLNd·Ô<˙w*
  6334. ?    SUBQ.W     #1,D1                 ; Decrement count for DBRA°dONLNd!˘<s*
  6335. ChksumLoop:°dONLNd-<^*
  6336. :    MOVE.B     (A1)+,D0              ; read a byte into D0°dONLNdh
  6337. <^*
  6338. :    ADD.W      D0,D3                 ; accumulate checksum°dONLNd£<"^*
  6339. :    ROL.W      #1,D3                 ; rotate left one bit°dONLNdfi!<,Y*
  6340. 9    DBRA       D1,ChksumLoop         ; loop if more bytes°dONLNd+<6_*
  6341.     RTS°dONLNd 5<@d*
  6342.     ENDP°dONLNd)I<TÆ*J;_________________________________________________________________________°dONLNdtS<^A*
  6343. ;°dONLNdv]<hå*
  6344. ; SL_TheListener°dONLNdág<rA*
  6345. ;°dONLNdâq<|Æ*
  6346. J;_________________________________________________________________________°dONLNd‘Ö<êÆ*J;_________________________________________________________________________°dONLNdè<öA*
  6347. ;°dONLNd!ô<§ê*
  6348. D; SL_TheListener - process packets received at the designated socket°dONLNdf£<ÆA*
  6349. ;°dONLNdh≠<∏s*
  6350. ;    Input:°dONLNdt∑<¬@*
  6351. 4;     D0 (byte) = packet's destination socket number°dONLNd©¡<ÃT*
  6352. 8;     D1 (word) = number of bytes left to read in packet°dONLNd‚À<÷*
  6353. (;     A0 points to the bytes to checksum°dONLNd ’<‡*
  6354. (;     A1 points to the bytes to checksum°dONLNd4fl<Í*
  6355. (;     A2 points to MPP's local variables°dONLNd]È<ÙE*
  6356. 5;     A3 points to next free byte in Read Header Area°dONLNdìÛ<˛E*
  6357. 5;     A4 points to ReadPacket and ReadRest jump table°dONLNd…˝<A*
  6358. ;°dONLNdÀ<x*
  6359. ;    Return:°dONLNdÿ<†*
  6360. ;     D0 is modified°dONLNdÌ<&˙*
  6361. &;     D3 (word) = accumulated checksum°dONLNd%<0Æ*
  6362. J;_________________________________________________________________________°dONLNd_9<D“*SL_TheListener  PROC    EXPORT°dONLNd~M<X¥*    WITH    PacketBuffer°dONLNdóa<lı*%; get pointer to current PacketBuffer°dONLNdΩu<Än*
  6363. GetBuffer:°dONLNd»<ä€*
  6364. S    LEA       current_qelem,A3                ; get the pointer to the PacketBuffer°dONLNd"âîK+ÿ
  6365.    ; to use ¡X¡
  6366. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷ˇ9) of 61(ÏZM.NW.AppleTalk2ˇÿ◊#ˇ ˇˇˇˇ#◊ 
  6367. IR,Times
  6368. .+6-Macintosh Technical Notes /4/˘,
  6369. Courier
  6370.     °dONLNd(Å*    MOVE.L    (A3),A3°dONLNd'2b*
  6371. B    MOVE.L    A3,D0                           ; if no PacketBuffer°dONLNdY1<b*
  6372. B    BEQ.S     NoBuffer                        ; then ignore packet°dONLNdúEP*4; read rest of packet into PacketBuffer.datagramData°dONLNd—Ydg*C    MOVE.L    D1,D3                           ; read rest of packet°dONLNdcnX*
  6373. @    LEA       buffer_data(A3),A3              ; A3 = ^bufferData°dONLNdVmx0*
  6374. 8    JSR       2(A4)                           ; ReadRest°dONLNdèwÇq*
  6375. E    BEQ.S     ProcessPacket                   ; If no error, continue°dONLNd’Ååº*
  6376. T    BRA       RcvRTS                          ; there was an error, so ignore packet°dONLNd*ï†Æ*; No buffer; ignore the packet°dONLNdI©¥∑*SNoBuffer      CLR D3                          ; Set to ignore packet (buffer size =°dONLNd£≥æ+ÿ
  6377.    ; 0)°dONLNd´Ω»0(‰68    JSR       2(A4)                           ; ReadRest°dONLNd‰«“≠*
  6378. Q    BRA       GetNextBuffer                   ; We missed this packet, but maybe °dONLNd;—‹∏+ÿ
  6379. (   ; there will be a buffer for the next°dONLNdj€Ê,*
  6380.    ; packet…°dONLNdwÔ˙÷(6&; Process the packet you just read in.°dONLNdû˘Ä*
  6381. H; ReadRest has been called so registers A0-A3 and D0-D3 are free to use.°dONLNdÁ≥*
  6382. ; We'll use registers this way:°dONLNd
  6383. ?*
  6384. ;PktBuff         EQU    A0        ; the current PacketBuffer°dONLNdC"≠*
  6385. QMPPLocals       EQU    A2        ; pointer to MPP's local variables (still set up°dONLNdñ!,b*
  6386. B                                 ;  from entry to socket listener)°dONLNdŸ+6D*
  6387. <HopCount        EQU    D0        ; used to get the hop count°dONLNd5@Ä*
  6388. HDatagramLength  EQU    D1        ; used to determine the datagram length°dONLNd_?Jè*
  6389. KSourceNetAddr   EQU    D2        ; used to build the source network address°dONLNd´S^^*ProcessPacket:°dONLNd∫]h{*
  6390. G    LEA        current_qelem,PktBuff          ; PktBuff = current_qelem°dONLNdgr∏*
  6391.      MOVE.L     (PktBuff),PktBuff°dONLNd#{ÜX*@; do everything that's common to both long and short DDP headers°dONLNddèöô*M; first, clear buffer_Type and buffer_NodeID to ensure their high bytes are 0°dONLNd≤£Æ]*A    CLR.W      buffer_Type(PktBuff)           ; clear buffer_Type°dONLNdÙ≠∏g*
  6392. C    CLR.W      buffer_NodeID(PktBuff)         ; clear buffer_NodeID°dONLNd8¡Ã5*9; clear SourceNetAddr to prepare to build network address°dONLNdr’‡ô*M    MOVEQ      #0,SourceNetAddr               ; build the network address in °dONLNdΔflÍJ+ÿ
  6393.    ; SourceNetAddr°dONLNdŸÛ˛w(6; get the hop count°dONLNdÌ˝≠*
  6394. Q    MOVE.W     toRHA+lapHdSz+ddpLength(MPPLocals),HopCount ; Get hop/length field°dONLNd?è*
  6395. K    ANDI.W     #DDPHopsMask,HopCount          ; Mask off the hop count bits°dONLNdã®*
  6396. P    LSR.W      #2,HopCount                    ; shift hop count into low bits of°dONLNd‹&E*
  6397.     high byte°dONLNdÁ%0ô*
  6398. M    LSR.W      #8,HopCount                    ; shift hop count into low byte°dONLNd    5/:≠*
  6399. Q    MOVE.W     HopCount,buffer_Hops(PktBuff)  ; and move it into the PacketBuffer°dONLNd    áCN*2; get the packet length (including the DDP header)°dONLNd    ∫MX∑*
  6400. S    MOVE.W     toRHA+lapHdSz+ddpLength(MPPLocals),DatagramLength ; Get length field°dONLNd
  6401. Wbè*
  6402. K    ANDI.W     #ddpLenMask,DatagramLength     ; Mask off the hop count bits°dONLNd
  6403. Zkv*2; now, find out if the DDP header is long or short°dONLNd
  6404. çäD*<    MOVE.B     toRHA+lapType(MPPLocals),D3    ; Get LAP type°dONLNd
  6405.  âî∑*
  6406. S    CMPI.B     #shortDDP,D3                   ; is this a long or short DDP header? ¡4¡˘
  6407. *&10)
  6408.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇÓ◊#ˇ ˇˇˇˇ#◊ 
  6409. IR,Times
  6410. .+Z-Developer Support Center(-Á January 1993 /X/,
  6411. Courier
  6412.     °dONLNd<(§(DZH    BEQ.S      IsShortHdr                     ; skip if short DDP header°dONLNdI1<<¥*; it's a long DDP header°dONLNdbE<P—*Q    MOVE.B     toRHA+lapHdSz+ddpType(MPPLocals),buffer_Type+1(PktBuff) ; get DDP °dONLNdºOÄZ¡(vû
  6413.        ; type°dONLNd c<n≥(äZK    MOVE.B     toRHA+lapHdSz+ddpDstNode(MPPLocals),buffer_NodeID+1(PktBuff)°dONLNdm<x‡*
  6414. T                                              ; get destination node from LAP header°dONLNdlÅ<åw*?    MOVE.L     toRHA+lapHdSz+ddpSrcNet(MPPLocals),SourceNetAddr°dONLNd≠ã<ñ©*
  6415. I                                              ; source network in hi word°dONLNd˜ï<†ö*
  6416. F                                              ; source node in lo byte°dONLNd>ü<™‡*
  6417. T    LSL.W      #8,SourceNetAddr               ; shift source node up to high byte of°dONLNdô©¥U+ÿ
  6418.  
  6419.    ; low word°dONLNdß≥<æ—(⁄ZQ                                              ; get source socket from DDP header°dONLNd˘Ω<»w*
  6420. ?    MOVE.B     toRHA+lapHdSz+ddpSrcSkt(MPPLocals),SourceNetAddr°dONLNd:—<‹€*S    SUB.W      #ddpType+1,DatagramLength      ; DatagramLength = number of bytes in°dONLNdî€ÊU+ÿ
  6421.  
  6422.    ; datagram°dONLNd¢Â<√( Z    BRA.S      MoveToBuffer°dONLNdæ˘<å*; checksum time…°dONLNdœ<«*
  6423. O    TST.W      toRHA+lapHdSz+ddpChecksum(MPPLocals) ;Does packet have checksum?°dONLNd
  6424. <π*
  6425.     BEQ.S      noChecksum°dONLNd9!<,*$; Calculate checksum over DDP header°dONLNd^+<6§*
  6426. H    MOVE.L     DatagramLength,-(SP)           ; save DatagramLength (D1)°dONLNdß?<Jê*D    CLR        D3                             ; set checksum to zero°dONLNdÏI<T¬*
  6427. N    MOVEQ      #ddphSzLong-ddpDstNet,D1       ; D1 = length of header part to °dONLNdAS^U+ÿ
  6428.  
  6429.    ; checksum°dONLNdO]<h÷(ÑZR                                              ; pointer to dest network number in °dONLNdßgr_+ÿ
  6430.    ; DDP header°dONLNd∑q<|@(òZ4    LEA        toRHA+lapHdSz+ddpDstNet(MPPLocals),A1°dONLNdÌ{<Ü≥*
  6431. K    JSR        SL_DoChksum                    ; checksum of DDP header part°dONLNd:Ö<ê«*
  6432. O                                              ; (D3 holds accumulated checksum)°dONLNdäô<§'*/; Calculate checksum over data portion (if any)°dONLNd∫≠<∏ã*C    MOVE.L     buffer_Data(PktBuff),A1        ; pointer to datagram°dONLNd˛∑<¬≥*
  6433. K    MOVE.L     (SP)+,DatagramLength           ; restore DatagramLength (D1)°dONLNdJ¡<ç*
  6434. H    MOVE.L     DatagramLength,-(SP)           ; save DatagramLength (D1)°dONLNdîÀ<÷≥*
  6435. K                                              ;  before calling SL_DoChksum°dONLNd‡’<‡¬*
  6436. N    BEQ.S      TestChecksum                   ; don't checksum datagram if its°dONLNd5flÍ_+ÿ
  6437.    ; length = 0°dONLNdEÈ<ÙΩ(ZM    JSR        SL_DoChksum                    ; checksum of DDP datagram part°dONLNdîÛ<˛«*
  6438. O                                              ; (D3 holds accumulated checksum)°dONLNd‰<}*
  6439. TestChecksum:°dONLNdÚ<≥*
  6440. K    MOVE.L     (SP)+,DatagramLength           ; restore DatagramLength (D1)°dONLNd    >%<0Î*#; Now make sure the checksum is OK.°dONLNd    b9<DΩ*M    TST.W      D3                             ; is the calculated value zero?°dONLNd    ∞C<Nã*
  6441. C    BNE.S      NotZero                        ; no -- go and use it°dONLNd    ÙM<Xã*
  6442. C    SUBQ.W     #1,D3                          ; it is 0; make it -1°dONLNd
  6443. 8a<ld*NotZero:°dONLNd
  6444. Ak<vJ*
  6445. 6    CMP.W      toRHA+lapHdSz+ddpChecksum(MPPLocals),D3°dONLNd
  6446. xu<Äh*
  6447. <    BNE.S      ChecksumErr                    ; Bad checksum°dONLNd
  6448. µ<äY*
  6449. 9    MOVE.W     #0,buffer_CheckSum(A0)         ; no errors°dONLNd
  6450. Ôâ<îπ*
  6451.     BRA.S      noChecksum ¡X¡
  6452. *&(NW 13 - AppleTalk: The Rest of the Story(÷˙11)
  6453.  of 61(ÏZM.NW.AppleTalk2ˇ|◊#ˇ ˇˇˇˇ#◊ 
  6454. IR,Times
  6455. .+6-Macintosh Technical Notes /4/˘,
  6456. Courier
  6457.     °dONLNd(T* ChecksumErr:°dONLNd
  6458. '2b*
  6459. B    MOVE.W     #ckSumErr,buffer_CheckSum(PktBuff) ; checksum error°dONLNdP;FO* noChecksum:°dONLNd\EPü*
  6460.     BRA.S      MoveToBuffer°dONLNdxcnï*; it's a short DDP header°dONLNdíwÇO* IsShortHdr:°dONLNdûÅå≤*
  6461. R    MOVE.B     toRHA+lapHdSz+sddpType(MPPLocals),buffer_Type+1(PktBuff) ; get DDP °dONLNd˙ãÄñû(≤û; type°dONLNdï†b(º6B    MOVE.B     toRHA+lapDstAdr(MPPLocals),buffer_NodeID+1(PktBuff)°dONLNdEü™£*
  6462. O                                               ; get destination node from LAP °dONLNdö©¥,+ÿ
  6463.     ; header°dONLNdß≥æ∑(⁄6S    MOVE.B     toRHA+lapSrcAdr(MPPLocals),SourceNetAddr ; get source node from LAP °dONLNdΩ»Z+¸
  6464.       ; header°dONLNd«“∑(Ó6S    LSL.W      #8,SourceNetAddr                ; shift src node up to high byte of °dONLNdi—‹6+ÿ
  6465.     ; low word°dONLNdx€ÊX(6@    MOVE.B     toRHA+lapHdSz+sddpSrcSkt(MPPLocals),SourceNetAddr°dONLNd∫Â≤*
  6466. R                                               ; get source socket from short DDP °dONLNdÔ˙,+ÿ
  6467.     ; header°dONLNd˘º( 6T    SUB.W      #sddpType+1,DatagramLength      ; DatagramLength = number of bytes in°dONLNdz6+ÿ
  6468.     ; datagram°dONLNdâ"Y(>6
  6469. MoveToBuffer:°dONLNdó!,*
  6470. 4    MOVE.L     SourceNetAddr,buffer_Address(PktBuff)°dONLNdÕ+6≠*
  6471. Q                                               ;move source network address into °dONLNd$5@J+ÿ
  6472.     ; PacketBuffer°dONLNd7?J&(f66    MOVE.W     DatagramLength,buffer_ActCount(PktBuff)°dONLNdoITè*
  6473. K                                               ; move datagram length into °dONLNd¡S^J+ÿ
  6474.     ; PacketBuffer°dONLNd‘q|û(ò6N; Now that we're done with the PacketBuffer, enqueue it into the usedQ and get°dONLNd#{Ü*
  6475. 4; another buffer from the freeQ for the next packet.°dONLNdXèö]*A    LEA        used_queue,A1                   ; A1 = ^used_queue°dONLNdöô§∑*
  6476. S    MOVE.L     (A1),A1                         ; A1 = used_queue (pointer to usedQ)°dONLNdÓ£Æ≤*
  6477. R    _Enqueue                                   ; put the PacketBuffer in the usedQ°dONLNdA∑¬^*GetNextBuffer:°dONLNdP¡Ã]*
  6478. A    LEA        free_queue,A1                   ; A1 = ^free_queue°dONLNdíÀ÷∑*
  6479. S    MOVE.L     (A1),A1                         ; A1 = free_queue (pointer to freeQ)°dONLNdÊ’‡º*
  6480. T    LEA        current_qelem, A0               ; copy freeQ.qHead into current_qelem°dONLNd;flÍ©*
  6481.     MOVE.L     qHead(A1),(A0)°dONLNdYÈÙ]*
  6482. A    MOVEA.L    qHead(A1),A0                    ; A0 = freeQ.qHead°dONLNdõÛ˛T*
  6483.     _Dequeue°dONLNd®;*RcvRTS:°dONLNd∞]*
  6484. A    RTS                                        ; return to caller°dONLNdÚ&@*
  6485.     ENDP°dONLNd˚/:ä*J;_________________________________________________________________________°dONLNdF9D?*
  6486. ;; Function SL_InitSktListener(freeQ, usedQ: QHdrPtr): OSErr°dONLNdÇCN*
  6487. ;°dONLNdÑMX*
  6488. ;°dONLNdÜalÆ*SL_InitSktListener PROC EXPORT°dONLNd•uÄ{*GStackFrame     RECORD    {A6Link},DECR     ; build a stack frame record°dONLNdÌä≠*
  6489. QResult1        DS.W      1                 ; function's result returned to caller°dONLNd    ?âîû*
  6490. NParamBegin     EQU       *                 ; start parameters after this point ¡4¡˘
  6491. *&12)
  6492.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ\◊#ˇ ˇˇˇˇ#◊ 
  6493. IR,Times
  6494. .+Z-Developer Support Center(-Á January 1993 /X/,
  6495. Courier
  6496.     °dONLNd<(h(DZ<freeQ          DS.L      1                 ; freeQ parameter°dONLNd='<2h*
  6497. <usedQ          DS.L      1                 ; usedQ parameter°dONLNdz1<<¬*
  6498. NParamSize      EQU       ParamBegin-*      ; size of all the passed parameters°dONLNd…;<F≥*
  6499. KRetAddr        DS.L      1                 ; placeholder for return address°dONLNdE<Pê*
  6500. DA6Link         DS.L      1                 ; placeholder for A6 link°dONLNdZO<Z∏*
  6501. LLocalSize      EQU       *                 ; size of all the local variables°dONLNdßY<dõ*
  6502.                ENDR°dONLNdªm<xã*C    WITH       StackFrame,QHdr             ; use these record types°dONLNdˇÅ<å≥*K    LINK       A6,#LocalSize               ; allocate our local stack frame°dONLNdKï<†«*O; copy the queue header pointers into our local storage for use in the listener°dONLNdõ©<¥ü*G    LEA        used_queue,A0               ; copy usedQ into used_queue°dONLNd„≥<æÕ*
  6503.     MOVE.L     usedQ(A6),(A0)°dONLNd«<“ü*G    LEA        free_queue,A0               ; copy freeQ into free_queue°dONLNdI—<‹Õ*
  6504.     MOVE.L     freeQ(A6),(A0)°dONLNdgÂ<§*H; dequeue the first buffer record from freeQ and set current_qelem to it°dONLNd∞˘<T*8    MOVEA.L    freeQ(A6),A1                ; A1 = ^freeQ°dONLNdÈ<Ã*
  6505. P    LEA        current_qelem, A0           ; copy freeQ.qHead into current_qelem°dONLNd:
  6506. <Õ*
  6507.     MOVE.L     qHead(A1),(A0)°dONLNdX<"m*
  6508. =    MOVEA.L    qHead(A1),A0                ; A0 = freeQ.qHead°dONLNdñ!<,x*
  6509.     _Dequeue°dONLNd£+<6^*
  6510. :    MOVE.W     D0,Result1(A6)              ; Return status°dONLNdfi?<Jm*=@1  UNLK       A6                          ; destroy the link°dONLNdI<T§*
  6511. H    MOVEA.L    (SP)+,A0                    ; pull off the return address°dONLNdeS<^—*
  6512. Q    ADDA.L     #ParamSize,SP               ; strip all of the caller's parameters°dONLNd∑]<hÅ*
  6513. A    JMP        (A0)                        ; return to the caller°dONLNd˘g<rd*
  6514.     ENDP°dONLNd{<Üê*D    END                                    ; end of this source file
  6515. °dONLNdGë<ùÎ* Initializing the Socket Listener°dONLNdh™<∂*.To initialize the socket listener, define the °dONLNdñ™∂g)Δfree and used queue °dONLNd™©gµÉ)eQHdr°dONLNdÆ™É∂˛) variables. You’ll need to°dONLNd…∂<¬æ(fiZTdefine a PacketBuffer structure to match the record structure defined in the socket °dONLNd∂æ¬˛(fi‹listener code.°dONLNd,√<œº(ÎZIf you add any new fields, °dONLNdG√ºœI)Äthen you need to modify the °dONLNdc¬IŒù)ç PacketBuffer°dONLNdo√ùœ˛)T structure defined in°dONLNdÖ–<‹:(¯Z7the listener code. In the sample below, an array of 10 °dONLNdºœ:€ï)˛
  6516. PacketBuffers°dONLNd…–ï‹£)[ is °dONLNdÕ–£‹˛)declared.  Initialize°dONLNd„›<Èq(Z the buffer °dONLNdÓ›qÈë)57packets, then queue them into the free queue using the °dONLNd%‹ëË…(Ø_Enqueue°dONLNd-›…È˛)8  trap. Call°dONLNd9È<ı∫(ZSL_InitSktListener°dONLNdKÍ∫ˆP)~ and pass the addresses of the °dONLNdjÈPıl)ñQHdr°dONLNdnÍlˆË) variable for the free and °dONLNdâÍˈ˛)|used°dONLNdéˆ<`(Z<queues. The following Pascal code demonstrates this process:
  6517.     °dONLNdÀ<*,USES MEMTYPES, QUICKDRAW, OSINTF, APPLETALK;°dONLNd¯"<-U*CONST°dONLNd˛,<7õ*
  6518.   ddpMaxData = 586; ¡X¡
  6519. *É(NW 13 - AppleTalk: The Rest of the Story(÷˙13)
  6520.  of 61(ÏZM.NW.AppleTalk2ˇ 6◊#ˇ ˇˇˇˇ#◊ 
  6521. IR,Times
  6522. .+6-Macintosh Technical Notes /4/˘,
  6523. Courier
  6524.     °dONLNd(,*TYPE°dONLNd'2ï*
  6525.     PacketBuffer = RECORD°dONLNd1<ê*
  6526.         qLink: QElemPtr;°dONLNd8;Fã*
  6527.         qType: Integer;°dONLNdPEP©*
  6528.         buffer_Type: Integer;°dONLNdnOZ≥*
  6529.         buffer_NodeID: Integer;°dONLNdéYd¬*
  6530. "        buffer_Address: AddrBlock;°dONLNd±cn©*
  6531.         buffer_Hops: Integer;°dONLNdœmxΩ*
  6532. !        buffer_ActCount: Integer;°dONLNdÒwÇ≥*
  6533.         buffer_CheckSum: OSErr;°dONLNdÅå0*
  6534. 8        buffer_Data: ARRAY[1..ddpMaxData] OF SignedByte;°dONLNdJãñ@*
  6535.     END;°dONLNdSü™'*VAR°dONLNdW©¥ã*
  6536.     freeQ, usedQ: QHdr;°dONLNdo≥æÍ*
  6537. *    Buffers: ARRAY[1..10] OF PacketBuffer;°dONLNdö—‹ï*PROCEDURE SL_TheListener;°dONLNd¥€ÊE*
  6538.     External;°dONLNdæÔ˙?*;FUNCTION SL_InitSktListener (freeQ, usedQ: QHdrPtr): OSErr;°dONLNd˙˘E*
  6539.     External;°dONLNd
  6540. Æ*PROCEDURE SetUpSocketListener;°dONLNd#";*
  6541.     VAR°dONLNd+!,w*
  6542.         err: OSErr;°dONLNd?+6w*
  6543.         i: Integer;°dONLNdS?JE*        BEGIN°dONLNd]IT∑*
  6544. S        freeQ.QHead := NIL;                  { initialize to nil to indicate empty °dONLNd∂S^'+ÿ
  6545.     queue }°dONLNd¬]h∑(Ñ6S        freeQ.QTail := NIL;                  { initialize to nil to indicate end of°dONLNdgr'+ÿ
  6546.     queue }°dONLNd({Ü∑(¢6S        usedQ.QHead := NIL;                  { initialize to nil to indicate empty °dONLNdÅÖê'+ÿ
  6547.     queue }°dONLNdçèö∑(∂6S        usedQ.QTail := NIL;                  { initialize to nil to indicate end of°dONLNdÁô§'+ÿ
  6548.     queue }°dONLNdÛ≠∏ü(‘6        FOR i := 1 TO 10 DO°dONLNd∑¬Â*
  6549. )            Enqueue(@Buffers[i], @freeQ);°dONLNd9À÷*2        err := SL_InitSktListener(@freeQ, @usedQ);°dONLNdl’‡§*
  6550.         IF err <> noErr THEN°dONLNdâflÍm*
  6551.             BEGIN°dONLNdõÈÙ
  6552. *
  6553. 1                { Perform error processing here }°dONLNdÕÛ˛h*
  6554.             END;°dONLNdfi˝@*
  6555.     END;
  6556. °dONLNdÁ"*9For C programmers, the initialization code is as follows:
  6557.     °dONLNd!+6Å*#include    <types.h>°dONLNd75@ï*
  6558. #include    <appletalk.h>°dONLNdQ?Jã*
  6559. #include    <OSUtils.h>°dONLNdiITÅ*
  6560. #include    <stdio.h>°dONLNd]hê*#define ddpMaxData   586 ¡4¡˘
  6561. *R14)
  6562.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇB◊#ˇ ˇˇˇˇ#◊ 
  6563. IR,Times
  6564. .+Z-Developer Support Center(-Á January 1993 /X/,
  6565. Courier
  6566.     °dONLNd<(å(DZtypedef struct {°dONLNd'<2™*
  6567.     QElemPtr    qLink;°dONLNd(1<<™*
  6568.     short       qType;°dONLNd?;<F6*
  6569. 2    short       buffer_type;        /* DDP Type */°dONLNdrE<P^*
  6570. :    short       buffer_NodeID;      /* Destination Node */°dONLNd≠O<Z∏*
  6571. L    AddrBlock   buffer_Address;     /* Source Address in AddrBlock format */°dONLNd˙Y<d;*
  6572. 3    short       buffer_Hops;        /* Hop count */°dONLNd.c<n|*
  6573. @    short       buffer_ActCount;    /* length of DDP datagram */°dONLNdom<x|*
  6574. @    OSErr       buffer_CheckSum;    /* Checksum returned here */°dONLNd∞w<Çw*
  6575. ?    char        buffer_Data[ddpMaxData]; /* the DDP datagram */°dONLNdÅ<åá*
  6576. } PacketBuffer;°dONLNdï<†√*QHdr          freeQ, usedQ;°dONLNdü<™æ*
  6577. PacketBuffer  buffers[10];°dONLNd7Ω<»Õ*extern void SL_THELISTENER();°dONLNdU—<‹ö*Fextern pascal OSErr SL_INITSKTLISTENER (freeQ, usedQ: QHdrPtr): OSErr;°dONLNdúÂ<æ*void SetUpSocketListener()°dONLNd∑Ô<˙A*
  6578. {°dONLNdπ˘<á*
  6579.     OSErr  err;°dONLNd…<}*
  6580.  
  6581.     short  i;°dONLNd◊<"€*S    freeQ.QHead = nil;              /* initialize to nil to indicate empty queue */°dONLNd+!<,‡*
  6582. T    freeQ.QTail = nil;              /* initialize to nil to indicate end of queue */°dONLNdÄ5<@€*S    usedQ.QHead = nil;              /* initialize to nil to indicate empty queue */°dONLNd‘?<J‡*
  6583. T    usedQ.QTail = nil;              /* initialize to nil to indicate end of queue */°dONLNd)S<^»*    for (i = 0; i < 10; i++)°dONLNdF]<h'*
  6584. /        Enqueue((QElemPtr)&buffers[i], &freeQ);°dONLNdvq<|"*.    err = SL_INITSKTLISTENER (&freeQ, &usedQ);°dONLNd•{<ÜØ*
  6585.     if (err != noErr) {°dONLNdΩÖ<ê*
  6586. +        /* perform error processing here */°dONLNdÈè<öU*
  6587.     }°dONLNdÔô<§A*
  6588. }
  6589. °dONLNdÒØ<ªœ*Using the Socket Listener°dONLNd »<‘fl*"The socket listener is set in use °dONLNd-»fl‘)£    with the °dONLNd6«”F)/POpenSkt°dONLNd>»F‘˛)8$ function, or with the more specific°dONLNdc‘<‡â(˝Z POpenATPSkt°dONLNdn’â·á)M4 function. The program then periodically checks the °dONLNd¢‘ᇑ)˛ usedQ.QHead°dONLNd≠’‘·ı)M value °dONLNd¥’ı·˛)!to°dONLNd∑·<Ìt(    ZAdetermine whether the socket listener has processed a packet. If °dONLNd¯·tÌ˛(    íso, the packet is processed,°dONLNdÌ<˘t(ZDequeued°dONLNdÓt˙Ú)8 from the used queue, and °dONLNd7ÌÚ˘*)~Enqueued°dONLNd?Ó*˙fi)8) into the free queue. It’s also possible °dONLNdhÓfi˙˛)¥for the°dONLNdp˙<fl("Z#same socket listener to be used by °dONLNdì˙fl˛)£:separate processes in the program. If so, the program must°dONLNdŒ<á(.Zscan the list for °dONLNd‡á˛)KQthe desired packet(s). Note that if multiple packets are expected, it is possible°dONLNd2<P(:Zthat °dONLNd7P˛)Ythe program may process the first packet before the listener processes the second packet.°dONLNdë<+%(GZ.The program needs to be designed to check the °dONLNdø%*r)È usedQ.QHead°dONLNd r+Ω)M value later for °dONLNd€Ω+˛)Kthe additional°dONLNdÍ+<7c(SZpackets.
  6590.     °dONLNdÛC<NP*TYPE°dONLNd¯M<Xπ*
  6591.     PacketBuffer = RECORD°dONLNdW<b¥*
  6592.         qLink: QElemPtr;°dONLNd+a<lØ*
  6593.         qType: Integer;°dONLNdCk<vÕ*
  6594.         buffer_Type: Integer;°dONLNdau<Ä◊*
  6595.         buffer_NodeID: Integer;°dONLNdÅ<äÊ*
  6596. "        buffer_Address: AddrBlock;°dONLNd§â<îÕ*
  6597.         buffer_Hops: Integer; ¡X¡
  6598. *&(NW 13 - AppleTalk: The Rest of the Story(÷˙15)
  6599.  of 61(ÏZM.NW.AppleTalk2ˇ
  6600. ◊#ˇ ˇˇˇˇ#◊ 
  6601. IR,Times
  6602. .+6-Macintosh Technical Notes /4/˘,
  6603. Courier
  6604.     °dONLNd(Ω*!        buffer_ActCount: Integer;°dONLNd"'2≥*
  6605.         buffer_CheckSum: OSErr;°dONLNdB1<0*
  6606. 8        buffer_Data: ARRAY[1..ddpMaxData] OF SignedByte;°dONLNd{;F@*
  6607.     END;°dONLNdÑOZÆ*    PacketPtr = ^PacketBuffer;°dONLNd£cn'*VAR°dONLNdßmxã*
  6608.     freeQ, usedQ: QHdr;°dONLNdøwÇã*
  6609.     bufPtr : PacketPtr;°dONLNd◊Åå1*
  6610.     .°dONLNd›ãñ1*
  6611.     .°dONLNd„ï†1*
  6612.     .°dONLNdÈ©¥û*N    WHILE (usedQ.QHead <> nil) DO             { check if packet available for °dONLNd>≥æE+ÿ
  6613.      processing }°dONLNdPΩ»Y(‰6
  6614.         BEGIN°dONLNd^«“q*
  6615. E            bufPtr := PacketPtr(usedQ.QHead);  { get the packet ptr }°dONLNd§—‹X*
  6616. @            IF (Dequeue(QElemPtr(bufPtr), @usedQ) <> noErr) THEN°dONLNd€ÊÅ*
  6617.                 BEGIN°dONLNd˚Ô˙*3                 { Process the packet information }°dONLNd/∑*S                 Enqueue(QElemPtr(bufPtr), @freeQ); { requeue the packet buffer for°dONLNdä
  6618. F+¸
  6619.  
  6620.     use. }°dONLNdï"w(>6                END°dONLNd©!,h*
  6621.             ELSE°dONLNd∫+6Å*
  6622.                 BEGIN°dONLNd–5@≤*
  6623. R                    { error occurred dequeueing packet - perform error processing °dONLNd%?ÑJß+l
  6624.  here }°dONLNd-IT|(p6                END;°dONLNdBS^T*
  6625.         END;
  6626. °dONLNdOiuI*@For C Programmers, the  socket listener code is used as follows:
  6627.     °dONLNdêÅåh*typedef struct {°dONLNd°ãñÜ*
  6628.     QElemPtr    qLink;°dONLNd∏ï†Ü*
  6629.     short       qType;°dONLNdœü™*
  6630. 2    short       buffer_type;        /* DDP Type */°dONLNd©¥:*
  6631. :    short       buffer_NodeID;      /* Destination Node */°dONLNd=≥æî*
  6632. L    AddrBlock   buffer_Address;     /* Source Address in AddrBlock format */°dONLNdäΩ»*
  6633. 3    short       buffer_Hops;        /* Hop count */°dONLNdæ«“X*
  6634. @    short       buffer_ActCount;    /* length of DDP datagram */°dONLNdˇ—‹X*
  6635. @    OSErr       buffer_CheckSum;    /* Checksum returned here */°dONLNd@€ÊS*
  6636. ?    char        buffer_Data[ddpMaxData]; /* the DDP datagram */°dONLNdÄÂc*
  6637. } PacketBuffer;°dONLNdê˘∏* typedef PacketBuffer *PacketPtr;°dONLNd±
  6638. ê*QHdr       freeQ, usedQ;°dONLNd "r*
  6639. PacketPtr  bufPtr;°dONLNd›!,1*
  6640.     .°dONLNd„+61*
  6641.     .°dONLNdÈ5@1*
  6642.     .°dONLNdÔIT®*P    while (usedQ.QHead != nil) {               /* check if packet available for °dONLNdES^T+ÿ
  6643.        processing */°dONLNdZ]h{(Ñ6G        bufPtr = (PacketPtr)usedQ.QHead;       /* get the packet ptr */°dONLNd¢gr0*
  6644. 8        if (Dequeue(QElemPtr(bufPtr), &usedQ) == noErr {°dONLNd€{ܲ*.            { Process the packet information } ¡4¡˘
  6645. *416)
  6646.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇb◊#ˇ ˇˇˇˇ#◊ 
  6647. IR,Times
  6648. .+Z-Developer Support Center(-Á January 1993 /X/,
  6649. Courier
  6650.     °dONLNd<(—(DZQ            Enqueue(QElemPtr(bufPtr), &freeQ);  /* requeue the packet buffer for °dONLNdW'2_+ÿ
  6651.         use. */°dONLNdg1<<i(XZ            }°dONLNdq;<FÇ*
  6652.         else {°dONLNdÄO<Z÷*R            /* error occurred dequeueing packet - perform error processing here */°dONLNd”Y<di*
  6653.             }°dONLNd›c<nU*
  6654.     }
  6655. °dONLNd„Ö<î*&The AppleTalk Transition Queue
  6656. °dONLNd†<¨*%The AppleTalk Transition Queue keeps °dONLNd'†¨˛) 0applications and other resident processes on the°dONLNdX¨<∏r(‘Z
  6657. Macintosh °dONLNdb¨r∏˛)6Jinformed of AppleTalk events, such as the opening and closing of AppleTalk°dONLNd≠∏<ƒN(‡Z:drivers, or changes to the Flagship name (to be discussed °dONLNdÁ∏Nƒ˛(‡l$later in this Note). A comprehensive°dONLNd ƒ<–«(ÏZdiscussion of the AppleTalk °dONLNd(ƒ«–l)ã!Transition Queue is presented in °dONLNdIƒl–ø)•Inside Macintosh°dONLNdYƒø–˛)S  Volume VI,°dONLNde–<‹#(¯Z,Chapter 32. New to the AppleTalk Transition °dONLNdë–#‹˛)Á)Queue are messages regarding the Flagship°dONLNdª‹<Ëfl(ZUNaming Service, the AppleTalk Multiple Node Architecture (also to be discussed later °dONLNd‹fl˲(˝in this°dONLNdË<Ùî(ZHNote), changes to processor speed that may affect LocalTalk timers, and °dONLNd`ËîÙ˛(≤a transition to indicate°dONLNdyÙ<·(Z"change of the network cable range.°dONLNdù <&*3Later in this section is a sample Transition Queue °dONLNd– &˛)Í,procedure in both C and Pascal that includes°dONLNd˝<$õ(@ZIthe known transition selectors. There is also a sample Pascal source for °dONLNdFõ$˛(@πdetermining whether°dONLNdZ%<1;(MZ4the LAP Manager version 53 or later exists. Calling °dONLNdé$;0z)ˇ    LAPAddATQ°dONLNdó%z1≈)? for AppleTalk °dONLNd¶%≈1˛)K versions 52°dONLNd≤1<=˛(YZ*and earlier will result in a system crash °dONLNd‹1˛=˛)¬1since the LAP Manager is not implemented prior to°dONLNd><Jq(fZ
  6658. AppleTalk °dONLNd>qJ!)5"version 53. The Boolean function, °dONLNd:=!Iu)∞ LAPMgrExists°dONLNdF>uJ˛)T, should be used instead of°dONLNdbK<W◊(sZchecking the low-memory global
  6659. °dONLNdÄK◊W⁄)õ 
  6660. °dONLNdÅJ⁄VJ)LAPMgrPtr, $0B18°dONLNdëKJWN)p.°dONLNdìc<oi(ãZ*Bug With LAPAddATQ and LAPRmvATQ Glue Code°dONLNdæ{<á‚*OA bug exists in the glue code for the LAPAddATQ and for the LAPRmvATQ routines °dONLNd
  6661. {‚á˛(£in the°dONLNdá<ìr(ØZ Interface.o °dONLNd árì˛)6Pfile. The same glue code is used with the Think C version 5.0.x product and will°dONLNdqì<ü∂(ªZaffect those users as well.°dONLNdé´<∑Ú*[In the glue code, these calls use the Pascal stack calling convention by allocating memory °dONLNdÈ´Ú∑˛(”on°dONLNdÏ∑<√u(flZ?the stack for the OSErr result. The ATQEntryPtr is then pushed °dONLNd+∑u√˛(flìonto the stack and the LAP°dONLNdF√<œÇ(ÎZAManager is called. Upon return from a JSR instruction to the LAP °dONLNdá√Çœ˛(ΆManager code, the return°dONLNd†œ<€∫(˜ZQaddress is placed in register A0 and the stack incremented. The glue code should °dONLNdÒœ∫€˛(˜ÿ
  6662. then move the°dONLNdˇ€<Á^(Z2-byte °dONLNd€^Á˛)"Wresult onto the stack into the location reserved for the result. Instead, the glue code°dONLNd^Á<ÛQ(Z:decrements the stack pointer by 2 bytes before moving the °dONLNdòÁQÛ˛(o$result onto the stack. The glue code°dONLNdΩÛ<ˇù(ZJjumps to the return address in register A0. Upon return, the stack is off °dONLNd    Ûùˇ˛(ªby 2 bytes. If local°dONLNd    ˇ< à('ZIvariables are used and are referenced from the stack pointer in register °dONLNd    eˇà ˛('¶A7, following the return°dONLNd    ~ <±(3ZOfrom these LAP Manager calls, access to the local variables may not be correct.°dONLNd    œ#</i*<The following Assembler glue code is supplied for MPW users °dONLNd
  6663. #i/˛(Káto assemble and link with their°dONLNd
  6664. +/<;™(WZprograms. For the °dONLNd
  6665. =/™;˛)n6remainder of this Tech Note, the call LAPAddATQFix and°dONLNd
  6666. t;<Ga(cZ3LAPRmvATQFix will be used instead and refer to the °dONLNd
  6667. ß;aG˛(cfollowing code. For Think C°dONLNd
  6668. √G<Sß(oZGprogrammers, the same functions are presented using in-line Assembler. °dONLNd
  6669. GßS˛(o≈For Think Pascal°dONLNd S<_>({Z2programmers, one solution is to compile the Think °dONLNd MS>_˛({\%C code and to link with the resulting°dONLNd s_<ku(áZ
  6670. Library file. ¡X¡
  6671. *O(NW 13 - AppleTalk: The Rest of the Story(÷˙17)
  6672.  of 61(ÏZM.NW.AppleTalk2ˇN◊#ˇ ˇˇˇˇ#◊ 
  6673. IR,Times
  6674. .+6-Macintosh Technical Notes /4/˘,
  6675. Courier
  6676.     °dONLNd(ä*J;_________________________________________________________________________°dONLNdK'2*
  6677. ;°dONLNdM1<J*
  6678.  
  6679. ; ATQFix.a°dONLNdX;Fä*
  6680. J;_________________________________________________________________________°dONLNd£EP*
  6681. ;°dONLNd•OZm*
  6682. ; DTS Code Sample°dONLNd∑Yd*
  6683. ;°dONLNdπcn¶*
  6684. ; ©1992 Apple Computer, Inc.°dONLNd÷mx*
  6685. ;°dONLNdÿwÇ+*
  6686. 7; Replacement code for LAPAddATQ and LAPRmvATQ in which°dONLNdÅåD*
  6687. <; the glue code in Interface.o does not restore the stack to°dONLNdNãñD*
  6688. <; its original condition.  Use the following code as opposed°dONLNdã*
  6689. "; to that in the Interface.o file.°dONLNdÆü™*
  6690. ;°dONLNd∞©¥ä*
  6691. J;_________________________________________________________________________°dONLNd˚Ω»*;°dONLNd˝«“O*
  6692. ; interface°dONLNd    —‹!*
  6693. 5; pascal OSErr LAPAddATQFix(ATQEntryPtr theATQEntry);°dONLNd?€Ê!*
  6694. 5; pascal OSErr LAPRmvATQFix(ATQEntryPtr theATQEntry);°dONLNduÔ˙§*LAPAddATQFix   PROC   EXPORT°dONLNdíq*E           MOVE.W     #$0017,D0       ; D0 selector $0017 = LAPAddATQ°dONLNdÿ
  6695. &*
  6696. 6           MOVEA.L    $0004(A7),A0    ; A0 -> ATQ Proc°dONLNd"b*
  6697. B           MOVEA.L    $0B18,A1        ; Set up to call LAP Manager°dONLNdR!,v*
  6698. F           MOVE.L     (A7)+,(A7)      ; Move return address up 4 bytes°dONLNdô+60*
  6699. 8           JSR        $0002(A1)       ; call LAP Manager°dONLNd“5@g*
  6700. C           MOVEA.L    (A7)+,A0        ; Move return address into A0°dONLNd?J®*
  6701. P           MOVE.W     D0,(A7)         ; Move result into space reserved on stack°dONLNdgIT˛*
  6702. .           JMP        (A0)            ; Return°dONLNdñ]hc*           ENDP°dONLNd¶q|§*LAPRmvATQFix   PROC   EXPORT°dONLNd√Öêq*E           MOVE.W     #$0018,D0       ; D0 selector $0018 = LAPRmvATQ°dONLNd    èö&*
  6703. 6           MOVEA.L    $0004(A7),A0    ; A0 -> ATQ Proc°dONLNd@ô§b*
  6704. B           MOVEA.L    $0B18,A1        ; Set up to call LAP Manager°dONLNdÉ£Æv*
  6705. F           MOVE.L     (A7)+,(A7)      ; Move return address up 4 bytes°dONLNd ≠∏0*
  6706. 8           JSR        $0002(A1)       ; call LAP Manager°dONLNd∑¬g*
  6707. C           MOVEA.L    (A7)+,A0        ; Move return address into A0°dONLNdG¡Ã®*
  6708. P           MOVE.W     D0,(A7)         ; Move result into space reserved on stack°dONLNdòÀ÷˛*
  6709. .           JMP        (A0)            ; Return°dONLNd«flÍc*           ENDP°dONLNd◊Û˛^*           END°dONLNdÊä*J;_________________________________________________________________________°dONLNd1|*
  6710. ; End File: ATQFix.a°dONLNdF&ä*
  6711. J;_________________________________________________________________________
  6712. °dONLNdë1=Y*@For Think C programmers, the following code sample can be used. °dONLNd—1Y=⁄(YwThink Pascal programmers°dONLNdÍ=I∫(e6Ycan link with the library file produced by compiling this code with the Think C compiler.
  6713.     °dONLNdDU`"*/*°dONLNdG_jè*
  6714. K *_________________________________________________________________________°dONLNdìitm*
  6715.  * File: ATQFix.c°dONLNd•s~è*
  6716. K *_________________________________________________________________________°dONLNdÒ}à"*
  6717.  *°dONLNdÙáír*
  6718.  * DTS Code Sample ¡4¡˘
  6719. *(18)
  6720.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇD◊#ˇ ˇˇˇˇ#◊ 
  6721. IR,Times
  6722. .+Z-Developer Support Center(-Á January 1993 /X/,
  6723. Courier
  6724.     °dONLNd<(F(DZ *°dONLNd'<2œ*
  6725.  * ©1992 Apple Computer, Inc.°dONLNd!1<<F*
  6726.  *°dONLNd$;<Fü*
  6727. G * Replacement code for LAPAddATQ and LAPRmvATQ for Think C programmers°dONLNdmE<P§*
  6728. H * to fix the glue code to fix a bug in the Think C library supplied via°dONLNd∑O<Z©*
  6729. I * the MPW Interface.o file.  The glue code does not restore the stack to°dONLNdY<dm*
  6730. = * its original condition.  Use the following code as opposed°dONLNd?c<n*
  6731. * * to that in the Think C library instead.°dONLNdjm<xF*
  6732.  *°dONLNdmw<Ç≥*
  6733. K *_________________________________________________________________________°dONLNdπÅ<åK*
  6734.  */°dONLNdΩï<†ë*#ifndef __TYPES__°dONLNdœü<™ñ*
  6735. #include <Types.h>°dONLNd‚©<¥Z*
  6736. #endif°dONLNdÈΩ<»Õ*#define LAPAddATQCall    0x17°dONLNd«<“Õ*
  6737. #define LAPRmvATQCall    0x18°dONLNd%—<‹“*
  6738. #define LAPMgrPtr        0xB18°dONLNdD€<Êæ*
  6739. #define LAPMgrCall       2°dONLNdaÔ<˙E*5/**********  Prototypes ****************************/°dONLNdó˘<;*
  6740. 3pascal OSErr LAPAddATQFix(ATQEntryPtr theATQEntry);°dONLNdÀ<;*
  6741. 3pascal OSErr LAPRmvATQFix(ATQEntryPtr theATQEntry);°dONLNdˇ!<,6*2pascal OSErr LAPAddATQFix(ATQEntryPtr theATQEntry)°dONLNd2+<6A*
  6742. {°dONLNd45<@}*
  6743.  
  6744.         asm {°dONLNdB?<J€*
  6745. S            MOVE.W     #LAPAddATQCall,D0          /* D0 selector $0017 = LAPAddATQ °dONLNdúI8TQ+¸
  6746.    */°dONLNd¢S<^ö(zZF            MOVEA.L    theATQEntry,A0             /* A0 -> ATQ Proc */°dONLNdÈ]<h÷*
  6747. R            MOVEA.L    LAPMgrPtr,A1               /* Set up to call LAP Manager */°dONLNd<g<r§*
  6748. H            JSR        LAPMgrCall(A1)             /* call LAP Manager */°dONLNdÖq<|Ã*
  6749. P            MOVE.W     D0,12(A6)                  /* move result in D0 onto the °dONLNd€{Ün+ÿ
  6750.           stack */°dONLNdÓÖ<êi(¨Z            }°dONLNd¯è<öA*
  6751. }°dONLNd˙£<Æ6*2pascal OSErr LAPRmvATQFix(ATQEntryPtr theATQEntry)°dONLNd-≠<∏A*
  6752. {°dONLNd/∑<¬}*
  6753.  
  6754.         asm {°dONLNd=¡<À*
  6755. S            MOVE.W     #LAPRmvATQCall,D0          /* D0 selector $0018 = LAPRmvATQ °dONLNdóÀ8÷Q+¸
  6756.    */°dONLNdù’<‡ö(¸ZF            MOVEA.L    theATQEntry,A0             /* A0 -> ATQ Proc */°dONLNd‰fl<Í÷*
  6757. R            MOVEA.L    LAPMgrPtr,A1               /* Set up to call LAP Manager */°dONLNd7È<Ù§*
  6758. H            JSR        LAPMgrCall(A1)             /* call LAP Manager */°dONLNdÄÛ<˛Ã*
  6759. P            MOVE.W     D0,12(A6)                  /* move result in D0 onto the °dONLNd÷˝n+ÿ
  6760.           stack */°dONLNdÈ<i(.Z            }°dONLNdÛ<A*
  6761. }°dONLNdı%<0F*/*°dONLNd¯/<:≥*
  6762. K *_________________________________________________________________________°dONLNdD9<D•*
  6763.  * End file: ATQFix.c°dONLNdZC<N≥*
  6764. K *_________________________________________________________________________°dONLNd¶M<XK*
  6765.  */
  6766. °dONLNd™c<o*&Calling the AppleTalk Transition Queue°dONLNd—{<áD*4System software version 7.0 requires the use of the °dONLNd{Dá˛(£b#MPW version 3.2 interface files and°dONLNd)á<ì·(ØZ#libraries. The AppleTalk interface °dONLNdLá·ì˛)•:presents two new routines for calling all processes in the ¡X¡
  6767. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙19)
  6768.  of 61(ÏZM.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  6769. IR,Times
  6770. .+6-Macintosh Technical Notes /4/˘
  6771. °dONLNd)é*JAppleTalk Transition Queue. Rather than use parameter block control calls °dONLNdJé)⁄(E¨as described in°dONLNdZ)5 (Q61M.NW.AppleTalk2Mac, use the ATEvent procedure or °dONLNdã) 5⁄(Q>%the ATPreFlightEvent function to send°dONLNd±5A(]6/transition notification to all queue elements. °dONLNd‡5AΩ)Ë"These procedures are discussed in °dONLNd5ΩA⁄)ΩInside°dONLNd    AMI(i6    Macintosh°dONLNdAIMø)1 Volume VI, Chapter 32.°dONLNd*Ye7(Å6Note:°dONLNd0Y<eò)$?You can call the ATEvent and ATPreFlightEvent routines only at °dONLNdoYòe∂(Å∂virtual°dONLNdwe<q-(çZ,memory safe time. See the Memory Management °dONLNd£e-qc)Ò chapter of °dONLNdÆecq∂)6Inside Macintosh°dONLNdøq<}X(ôZ9Volume VI, Chapter 28, for information on virtual memory.°dONLNd˘âï(±6'Standard AppleTalk Transition Constants°dONLNd!°≠T*CUse the following constants for the standard AppleTalk transitions:,
  6772. Courier
  6773.     °dONLNdeπƒ1*CONST°dONLNdkπ<ƒs)$ ATTransOpen°dONLNdwπæƒE)Ç= 0;     {open transition }°dONLNdî√<Œx(ÍZ ATTransClose°dONLNd°√æŒÅ)Ç'= 2;     {prepare-to-close transition }°dONLNd Õ<ÿå(ÙZATTransClosePrep°dONLNd€Õæÿê)Ç*= 3;     {permission-to-close transition }°dONLNd◊<‚ñ(˛ZATTransCancelClose°dONLNd◊æ‚m)Ç#= 4;     {cancel-close transition }°dONLNd?·<Ï¥(ZATTransNetworkTransition°dONLNdX·æÏÜ)Ç(= 5;     {.MPP Network ADEV Transition }°dONLNdÇÎ<ˆπ(ZATTransNameChangeTellTask°dONLNdúÎæˆï)Ç+= 6;     {change-Flagship-name transition }°dONLNd…ı<¥(ZATTransNameChangeAskTask°dONLNd‚ıæü)Ç-= 7;     {permission-to-change-Flagship-name °dONLNdˇ
  6774. ,+2
  6775. transition }°dONLNd"    <Ø(0ZATTransCancelNameChange°dONLNd:    æ∏)Ç2= 8;     {cancel-change-Flagship-name transition }°dONLNdn<ñ(:ZATTransCableChange°dONLNdÅæã)Ç)= 'rnge' {cable range change transition }°dONLNd¨<(ñ(DZATTransSpeedChange°dONLNdøæ(Y)Ç= 'sped' {change in cpu speed }
  6776. °dONLNdfl3?w([6+The following information concerns the new °dONLNd
  6777. 3w?⁄([ïtransitions from°dONLNd?K¿(h6ATTransNetworkTransition°dONLNd3@¿LÎ)®     through °dONLNd<?ÎKi)+ATTransSpeedChange°dONLNdN@iLm)~.°dONLNdRXd¿(Ä6The Flagship Naming Service°dONLNdnp|u*ISystem software version 7.0 allows the user to enter a personalized name °dONLNd∑pu|⁄(òìby which her system°dONLNdÀ|à-(§6will °dONLNd–|-à⁄)Rbe published when connected to an AppleTalk network. The System 'STR ' resource ID°dONLNd#àîŒ(∞6S–16413 is used to hold this name. The name (listed as Macintosh Name) can be up to °dONLNdvàŒî⁄(∞Ï31°dONLNdyî†ù(º6characters in length and can °dONLNdñîù†⁄)Ö@be set using the Sharing Setup Control Panel Device (cdev). This°dONLNd◊†¨˝(»6-resource is different from the Chooser name, °dONLNd†˝¨⁄)Â&System 'STR ' resource ID –16096. When°dONLNd+¨∏V(‘6@providing network services for a workstation, the Flagship name °dONLNdk¨V∏⁄(‘tshould be used so that the°dONLNdÜ∏ƒã(‡6user can personalize his °dONLNdü∏ãƒ⁄)sBworkstation name while maintaining the use of the Chooser name for°dONLNd‚ƒ–r(Ï6server connection °dONLNdÙƒr–⁄)ZIidentification. It’s important to note that the Flagship name resource is°dONLNd>–‹E(¯6
  6778. available °dONLNdH–E‹)-'only from system software version 7.0. °dONLNdo–‹⁄)À DTS recommends that applications°dONLNdê‹Ë(6,not change either of these 'STR ' resources.°dONLNdΩÙ*5Applications taking advantage of this feature should °dONLNdÚÙ⁄)˜*place an entry in the AppleTalk Transition°dONLNd     )((69Queue to stay informed as to changes to this name. Three °dONLNd    V) ⁄((G$new transitions have been defined to°dONLNd    { ã(46communicate Flagship °dONLNd    ê ã⁄)s?name changes between applications and other resident processes.°dONLNd    –$Í(@6(Support for the Flagship Naming Service °dONLNd    ¯Í$⁄)“/Transitions is provided starting from AppleTalk°dONLNd
  6779. ($0Ÿ(L6(version 56. Note that AppleTalk version °dONLNd
  6780. P$Ÿ0⁄)¡456 can be installed on pre-7.0 systems; however, the°dONLNd
  6781. Ö0<ã(X6MFlagship Naming Service is available only from system software 7.0 and later.
  6782. °dONLNd
  6783. ”HT¯*'The ATTransNameChangeAskTask Transition
  6784. °dONLNd
  6785. ˚_kR*@From Assembly language, the stack upon calling looks as follows: ¡4¡˘
  6786. *O20)
  6787.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇp◊#ˇ ˇˇˇˇ#◊ 
  6788. IR,Times
  6789. .+Z-Developer Support Center(-Á January 1993 /X/,
  6790. Courier
  6791.     °dONLNd<(“(DZATQEvent            RECORD   0°dONLNd'<2O*
  6792. 7ReturnAddr          DS.L     1      ; address of caller°dONLNdW1<<©*
  6793. ItheEvent            DS.L     1      ; = 7; ID of ATTransNameChangeAskTask°dONLNd°;<Fs*
  6794. transaction°dONLNd≠E<Ph*
  6795. <aqe                 DS.L     1      ; pointer to task record°dONLNdÍO<Z«*
  6796. OinfoPtr             DS.L     1      ; pointer to NameChangeInfo parameter block°dONLNd:Y<d¥*
  6797.                     ENDR
  6798. °dONLNdSp<|Q*The °dONLNdWoQ{≥)NameChangeInfo°dONLNdep≥|0)b record block is as follows
  6799.     °dONLNdÅà<ìÎ(ØZ#NameChangeInfoPtr: ^NameChangeInfo;°dONLNd•í<ù¥*
  6800. NameChangeInfo  = RECORD°dONLNdæú<߇*
  6801. T                    newObjStr:      Str32;         {new Flagship name to change to }°dONLNd¶<±€*
  6802. S                    name:           StringPtr;     {ptr to location to place ptr to°dONLNdn∞8ªo+¸
  6803.   process }°dONLNdz∫<≈^(·Z:                                                   {name }°dONLNdµƒ<œ™*
  6804.                   END;
  6805. °dONLNdÀ<ÁQ*The °dONLNd–⁄QÊ˘)ATTransChangeNameAskTask°dONLNdË€˘Áñ)®! is issued under system software °dONLNd    €ñÁ˛)ùversion 7.0 to inform°dONLNdÁ<ÛÃ(Z Flagship clients that a process °dONLNd?ÁÃÛ˛)ê<wants to change the Flagship name. Each AppleTalk Transition°dONLNd|Ù<·(ZQueue element that processes °dONLNdôÙ·˘)•the °dONLNdùÛ˘ˇ°)ATTransChangeNameAskTask°dONLNdµÙ°˛)® can inspect the°dONLNdΔ< ()ZNameChangeInfoPtr^.newObjStr°dONLNd‚
  6806. ø)ƒ( to determine the new Flagship name. If °dONLNd
  6807. ø
  6808. ˛)ø you deny the°dONLNd<e(6Z    request, °dONLNd eπ))you must set the °dONLNd1
  6809. πZ)TNameChangeInfoPtr^.name°dONLNdHZ˛)°# pointer with a pointer to a Pascal°dONLNdl<&G(BZ6string buffer containing the name of your application °dONLNd¢G&S(Beor°dONLNd§S&ä)  to the nil °dONLNd∞ä&˛)7pointer. The AppleTalk°dONLNd«&<2o(NZ Transition °dONLNd“&o2˛)3SQueue process returns this pointer. The requesting application can display a dialog°dONLNd&2<>µ(ZZRnotifying the user of the name of the application that refused the change request.°dONLNdyJ<Vj*<While processing this event, you can make synchronous calls °dONLNdµJjV˛(ràto the Name-Binding Protocol°dONLNd“V<bç(~ZC(NBP) to attempt to register your entity under the new name. It is °dONLNdVçb˛(~´recommended that you°dONLNd*b<nµ(äZ5register an entity using the new Flagship name while °dONLNd_bµn˛(ä” handling the°dONLNdln<z‰(óZATTransChangeNameAskTask°dONLNdÑo‰{ê)®" event. You should not deregister °dONLNd¶oê{˛)¨an older entity at this°dONLNdæ{<áÄ(£ZApoint. Your routine must return a function result of 0 in the D0 °dONLNdˇ{Äá˛(£ûregister, indicating that it°dONLNdá<ì’(ØZUaccepts the request to change the Flagship name, or a nonzero value, indicating that °dONLNdqá’ì˛(ØÛ    it denies°dONLNd{ì<üs(ªZ the request.°dONLNdà´<∑t*    Warning: °dONLNdí´Ñ∑∫)H    DTS does °dONLNdõ´∫∑⁄)64not recommend that you change the Flagship name. The°dONLNd–∑Ñ√„(fl¢Sharing Setup cdev °dONLNd„∑„√⁄)_1does not handle this event and the Macintosh name°dONLNd√Ñœü(΢?will not be updated to reflect this change if the cdev is open.
  6810. °dONLNdU€<Á(Z(The ATTransNameChangeTellTask Transition
  6811. °dONLNd~Ú<˛v*@From Assembly language, the stack upon calling looks as follows:
  6812. °dONLNdø
  6813. <l*ATQEvent°dONLNd»
  6814. Ñ®)HRECORD°dONLNdœ
  6815. ∫¿)60°dONLNd—<!x(=Z
  6816. ReturnAddr°dONLNd‹Ñ!ú)HDS.L°dONLNd·∫!¿)61°dONLNd„Ã!>); address of caller°dONLNd˜ <,l(HZtheEvent°dONLNd     Ñ,ú)HDS.L°dONLNd     ∫,¿)61°dONLNd     Ã,¯)2; = 6; ID of ATTransNameChangeTellTask transaction°dONLNd    :+<7N(SZaqe°dONLNd    >+Ñ7ú)HDS.L°dONLNd    C+∫7¿)61°dONLNd    E+Ã7\); pointer to task record°dONLNd    ^6<Bf(^ZinfoPtr°dONLNd    f6ÑBú)HDS.L°dONLNd    k6∫B¿)61°dONLNd    m6ÃBò)"; pointer to the new Flagship name°dONLNd    ëAÑMú(i¢ENDR
  6817. °dONLNd    ñY<eÜ(ÅZA process uses °dONLNd    •YÜeÌ)JATEvent to send the °dONLNd    πXÌdú)gATTransNameChangeTellTask°dONLNd    “Yúe˛)Ø to notify AppleTalk°dONLNd    Áe<qt(çZBTransition Queue clients that the Flagship name is being changed. °dONLNd
  6818. )etq˛(çíThe LAP Manager then calls°dONLNd
  6819. Dq<}‚(ôZXevery routine in the AppleTalk Transition Queue that the Flagship name is being changed. ¡X¡
  6820. *=(NW 13 - AppleTalk: The Rest of the Story(÷˙21)
  6821.  of 61(ÏZM.NW.AppleTalk2ˇF◊#ˇ ˇˇˇˇ#◊ 
  6822. IR,Times
  6823. .+6-Macintosh Technical Notes /4/˘
  6824. °dONLNd*¨*When the AppleTalk Manager °dONLNd¨*+)îcalls your routine with a ,
  6825. Courier°dONLNd5+)⁄)ATTransNameChangeTellTask°dONLNdO*6o(R6Otransition, the third item on the stack is a pointer to a Pascal string of the °dONLNdû*o6⁄(Rçnew Flagship name to°dONLNd≥6B[(^6be registered. °dONLNd¬6[B⁄)COYour process should deregister any entities under the old Flagship name at this°dONLNdBNJ(j6
  6826. time. You °dONLNdBJN⁄)2Rcan make synchronous calls to NBP to deregister an entity. Return a result of 0 in°dONLNdoNZa(v6the D0 register.°dONLNdÄfr3*Note°dONLNdÑf3r6):°dONLNdÜf<rD)    5When the AppleTalk Manager calls your process with a °dONLNdªfDr∂(ébTellTask transition (that°dONLNd’s<k(õZ is, with a °dONLNd‡skΔ)/routine selector of °dONLNdÙrΔ~u)[ATTransNameChangeTellTask°dONLNd
  6827. su∂)Ø
  6828. ), you cannot°dONLNd<ã(ßZ-prevent the Flagship name from being changed.°dONLNdIó£((ø6To °dONLNdLó(£⁄)Xsend notification that your process intends to change the Flagship name, use the ATEvent°dONLNd•§∞∂(Ã6function described above. Pass °dONLNdƒ£∂Øe)ûATTransNameChangeTellTask
  6829. °dONLNd›§e∞j)Ø 
  6830. °dONLNdfi§j∞y)as °dONLNd·§y∞⁄)the event parameter°dONLNdı∞ºè(ÿ6Pand a pointer to the new Flagship name (Pascal string) as the infoPtr parameter.
  6831. °dONLNdF»‘Ô*&The ATTransCancelNameChange Transition
  6832. °dONLNdmflÎR*@From Assembly language, the stack upon calling looks as follows:
  6833. °dONLNdƘH*ATQEvent°dONLNd∑˜`Ñ)HRECORD°dONLNdæ˜ñú)60°dONLNd¿T(*6
  6834. ReturnAddr°dONLNdÀ`x)HDS.L°dONLNd–ñú)61°dONLNd“®); address of caller°dONLNdÊ
  6835. H(56theEvent°dONLNdÔ
  6836. `x)HDS.L°dONLNdÙ
  6837. ñú)61°dONLNdˆ
  6838. ®»)0; = 8; ID of ATTransCancelNameChange transaction°dONLNd'$*(@6aqe°dONLNd+`$x)HDS.L°dONLNd0ñ$ú)61°dONLNd2®$8); pointer to task record°dONLNdL#`/x(K~ENDR
  6839. °dONLNdQ;G/(c6The °dONLNdU:/F–)ATTransCancelNameChange°dONLNdl;–G\)° transition complements the °dONLNdà:\F”)åATTransNameChange°dONLNdô:”F⁄)w-°dONLNdöGSI(p6AskTask°dONLNd°HITP)1 °dONLNd¢HPT2)+transition. Processes that acknowledged an °dONLNdÕG2S⁄)‚ATTransNameChangeAskTask°dONLNdÊUa•(}6transition will be sent the °dONLNdT•`F)çATTransCancelNameChange°dONLNdUFaö)° transition if a °dONLNd*Uöa⁄)T
  6840. later process°dONLNd8am‚(â6'disallows the change of Flagship name. °dONLNd_a‚m⁄) /Your process should deregister any NBP entities°dONLNdènz{(ñ6registered during     °dONLNd°n{zï)cthe °dONLNd•mïy=)ATTransNameChangeAskTask°dONLNdΩn=z⁄)® transition. You can make°dONLNd◊zÜ∂(¢6Zsynchronous calls to NBP to deregister an entity. Return a result of 0 in the D0 register.
  6841. °dONLNd2íûu*CSystem 7.0 Sharing Setup cdev / Flagship Naming Service Interaction
  6842. °dONLNdv©µÑ*LThe Flagship Naming Service is a new system service built into System 7. It °dONLNd¬©Ñµ⁄(—¢is used to publish°dONLNd’µ¡û(›6the workstation using the °dONLNdÔµû¡⁄)Ü8Flagship name. The Flagship Naming Service implements an°dONLNd(¡Õö(È6OAppleTalk Transition Queue element to respond to changes in the Flagship name. °dONLNdw¡öÕ⁄(È∏ For example,°dONLNdÑÕŸµ(ı6the Sharing Setup cdev can be °dONLNd¢ÕµŸ⁄)ù5used to reset the Flagship name. When a new Macintosh °dONLNdÿŸ‡(6(Flagship) name is entered in 
  6843. °dONLNdˆŸ‡Â⁄)»%Sharing Setup, Sharing Setup sends an°dONLNdÂÒ¿(6ATTransNameChangeAskTask
  6844. °dONLNd4Ê¿ÚΔ)® 
  6845. °dONLNd5ÊΔÚ®)*message to the AppleTalk Transition Queue °dONLNd_Ê®Ú⁄)‚
  6846. to request°dONLNdjÚ˛Ã(6Mpermission to change the Flagship name. The Flagship Naming Service receives °dONLNd∑ÚÃ˛⁄(Íthe°dONLNdª˛
  6847. ¿('6ATTransNameChangeAskTask
  6848. °dONLNd”ˇ¿ Δ)® 
  6849. °dONLNd‘ˇΔ ¯) transition °dONLNdflˇ¯ ⁄)2)and registers the new name under the type°dONLNd         B(36,“Workstation” on the local network. Sharing °dONLNd    5 B⁄(3`Setup follows with the°dONLNd    L#«(@6ATTransNameChangeTellTask
  6850. °dONLNd    e«$Œ)Ø 
  6851. °dONLNd    fŒ$p)to notify AppleTalk Transition °dONLNd    Öp$⁄)¢Queue clients that a°dONLNd    ö$0H(L6
  6852. change in °dONLNd    §$H0⁄)0OFlagship name will occur. The Flagship Naming Service responds by deregistering°dONLNd    Ù0<Ó(X6,the workstation under the old Flagship name.°dONLNd
  6853. !HTê*NIf an error occurs from the NBPRegister call, Flagship Naming Service returns °dONLNd
  6854. oHêT⁄(pÆa nonzero error
  6855. °dONLNd
  6856. T`µ(|6@(the error returned from NBPRegister) and a pointer to its name  °dONLNd
  6857. øTµ`⁄(|”in the°dONLNd
  6858. Δ`lπ(â6NameChangeInfoPtr^.Name°dONLNd
  6859. ›aπmÖ)°' field. Note that the Workstation name °dONLNd aÖm⁄)Ãis still registered°dONLNd myˆ(ï6/under the previous Flagship name at this point. ¡4¡˘
  6860. *A22)
  6861.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇû◊#ˇ ˇˇˇˇ#◊ 
  6862. IR,Times
  6863. .+Z-Developer Support Center(-Á January 1993 /X/
  6864. °dONLNd<)f(EZ0AppleTalk Remote Access Network Transition Event°dONLNd15<Ar*
  6865. AppleTalk °dONLNd;5rA˛)6IRemote Access allows you to establish an AppleTalk connection between two°dONLNdÖA<Mç(iZDMacintosh computers over standard telephone lines. If the Macintosh °dONLNd…AçM˛(i´you dial-in to is on an°dONLNd·M<Y∫(uZAppleTalk network, such °dONLNd˘M∫Y˛)~@as LocalTalk or Ethernet, your Macintosh becomes, effectively, a°dONLNd:Y<ec(ÅZ@node on that network. You are then able to use all the services °dONLNdzYce˛(ÅÅon the new network. Given this°dONLNdôe<qá(çZnew capability, °dONLNd©eáq˛)KLit is important that services running on your Macintosh be notified when new °dONLNdˆq<}√(ôZAppleTalk connections 
  6866. °dONLNd q√}˛)á0are established and broken. For this reason, the°dONLNd=}<â¿(•ZATTransNetworkTransition°dONLNdU}¿â≈)Ñ °dONLNdV}≈âô)*event has been added to AppleTalk version °dONLNdÄ}ôâ˛)‘57. With version 57°dONLNdîâ<ï¶(±ZNpresent, this event can be expected in system software version 6.0.5 or later.°dONLNd„°<≠÷*TInternally, both the AppleTalk Session Protocol (ASP) and the AppleTalk Data Stream °dONLNd7°÷≠˛(…ÙProtocol°dONLNd@≠<πõ(’ZF(ADSP) have been modified to respond to this transition event. When a °dONLNdÜ≠õπ˛(’πdisconnect transition°dONLNdúπ<≈·(·ZZevent is detected, these drivers close down sessions on the remote side of the connection.
  6867. °dONLNd˜—<›*'The ATTransNetworkTransition Transition
  6868. °dONLNdË<Ùv*@From Assembly language, the stack upon calling looks as follows:,
  6869. Courier
  6870. °dONLNd`< l*ATQEvent°dONLNdiÑ ®)HRECORD°dONLNdp∫ ¿)60°dONLNds <x(3Z
  6871. ReturnAddr°dONLNd~ Ñú)HDS.L°dONLNdÉ ∫¿)61°dONLNdÖ Ã>); address of caller°dONLNdô<"l(>ZtheEvent°dONLNd¢Ñ"ú)HDS.L°dONLNdß∫"¿)61°dONLNd©Ã"™)%; = 5; ID of ATTransNetworkTransition°dONLNdœ!<-N(IZaqe°dONLNd”!Ñ-ú)HDS.L°dONLNdÿ!∫-¿)61°dONLNd⁄!Ã-\); pointer to task record°dONLNdÛ,<8f(TZinfoPtr°dONLNd˚,Ñ8ú)HDS.L°dONLNd,∫8¿)61°dONLNd,Ã8»)*; pointer to the TNetworkTransition record°dONLNd.7ÑCú(_¢ENDR
  6872. °dONLNd3O<[Q(wZThe °dONLNd7NQZœ)TNetworkTransition°dONLNdIOœ[r)~# record block is passed as follows:
  6873. °dONLNdmg<s®(èZTNetworkTransition°dONLNdÄgµsŸ)yRECORD°dONLNdágÁsÌ)20°dONLNdâr<~f(öZprivate°dONLNdërµ~Õ)yDS.L°dONLNdñrÁ~Ì)21°dONLNdòr˘~„)'; pointer used internally by AppleTalk °dONLNd¬}ÁâÛ(•  °dONLNd≈}˘âS)  Remote Access°dONLNdŸà<îÑ(∞Z netValidProc°dONLNdÊàµîÕ)yDS.L°dONLNdÎàÁîÌ)21°dONLNdÌà˘î˚)+; pointer to the network validate procedure°dONLNdì<üñ(ªZnewConnectivity°dONLNd)ìµüÕ)yDS.B°dONLNd.ìÁüÌ)21°dONLNd0ì˘üÈ)(; true = new connectivity, false = loss °dONLNd[û˘™_*   of connectivity°dONLNdn©µµÕ(—”ENDR°dONLNds¿<ÃS(ËZ4Network Transition Event for AppleTalk Remote Access
  6874. °dONLNd®◊<„“*Network Transition events are °dONLNdΔ◊“„˛)ñ8generated by AppleTalk Remote Access to inform AppleTalk°dONLNdˇ„<Ô>( Z5Transition Queue applications and resident processes °dONLNd4„>Ô˛( \&that network connectivity has changed.°dONLNd[<¸©(ZThe type of change is °dONLNdq©¸¸)mindicated by the °dONLNdÇÔ¸˚¿)SNetTransPtr^.newConnectivity°dONLNdû¿¸˛)ƒ flag. If this°dONLNd≠¸<«($Z flag is true, a connection to a °dONLNdÕ¸«˛)ãAnew internet has taken place. In this case, all network addresses°dONLNd    <Â(1Z&will be returned as reachable. If the °dONLNd5ÂN)©newConnectivity°dONLNdD    N∞)i flag is false, certain °dONLNd\    ∞˛)bnetworks are no°dONLNdl<!2(=Z0longer reachable. Since AppleTalk Remote Access °dONLNdú2!˛)ˆ(is connection based, it has knowledge of°dONLNd≈!<-_(IZwhere °dONLNdÀ!_-˛)#Ma specific network exists. AppleTalk Remote Access can take advantage of that°dONLNd    -<95(UZ2knowledge during a disconnect to inform AppleTalk °dONLNd    K-59˛)˘*Transition Queue clients that a network is°dONLNd    v9<E.(aZ-no longer reachable. This information can be °dONLNd    £9.E˛)Ú&used by clients to age out connections°dONLNd     E<Q‡(mZ"immediately rather than waiting a °dONLNd    ÏE‡Q˛)§;potentially long period of time before discovering that the°dONLNd
  6875. (Q<]fl(yZ"other end is no longer responding.°dONLNd
  6876. Ki<u‚*SWhen AppleTalk Remote Access is disconnecting, it passes a network validation hook °dONLNd
  6877. ûi‚u˛(ëin the°dONLNd
  6878. •v<Ç•(ûZTNetworkTransition °dONLNd
  6879. ∏v•Ç–)irecord, °dONLNd
  6880. ¿u–Å)+NetTransPtr^.netValidProc
  6881. °dONLNd
  6882. ŸvÇã)Ø. 
  6883. °dONLNd
  6884. €vãDz) A client can use the°dONLNd
  6885. Ç<é(™Z(validation hook to ask AppleTalk Remote °dONLNd Çé˛)Δ5Access whether a specific network is still reachable. ¡X¡
  6886. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙23)
  6887.  of 61(ÏZM.NW.AppleTalk2ˇX◊#ˇ ˇˇˇˇ#◊ 
  6888. IR,Times
  6889. .+6-Macintosh Technical Notes /4/˘
  6890. °dONLNd)Ü*TIf the network is still reachable, the validate function will return true. A client °dONLNdTÜ)⁄(E§can then continue°dONLNdf)55(Q6=to check other networks of interest until the status of each °dONLNd£)55⁄(QS one has been determined. After a°dONLNdƒ5Ap(]6client has finished °dONLNdÿ5pA⁄)XGchecking networks, control returns to AppleTalk Remote Access where the°dONLNd AM˝(i61next AppleTalk Transition Queue client is called.°dONLNdRYeê*RThe information the network validation hook returns is valid only if a client has °dONLNd§Yêe⁄(ÅÆjust been called°dONLNdµeqd(ç6as a result of a °dONLNdΔedq⁄)LKtransition. A client can validate networks only when she has been called to°dONLNdq}ê(ô6Nhandle a Network Transition event. Note that the Network Transition event can °dONLNd`qê}⁄(ôÆbe called as the°dONLNdq}âz(•6Nresult of an interrupt, so a client should obey all of the normal conventions °dONLNdø}zâ⁄(•òinvolved with being°dONLNd”âï9(±6called °dONLNd⁄â9ï⁄)!Kat this time (for example, don’t make calls that move memory and don’t make°dONLNd&ï°U(Ω6 synchronous°dONLNd1ïU°ÿ)= Preferred AppleTalk calls).°dONLNdN≠π (’6YTo check a network number for validity the client uses the network validate procedure to °dONLNdß≠ π⁄(’Ëcall°dONLNd¨π≈±(·6UAppleTalk Remote Access. This call is defined using C calling conventions as follows:,
  6891. Courier
  6892.     °dONLNd—‹≠*Qpascal long netValidProc(TNetworkTransition *thetrans, unsigned long theAddress);°dONLNdUÂ<d+$thetrans°dONLNd^ÂÑì)H-->°dONLNdb®ª)$7Pass in the TNetworkTransition record given to you when°dONLNdûÔ®˙W*
  6893. #your transition handler was called.°dONLNd√<n(*Z
  6894. theAddress°dONLNdŒÑì)H-->°dONLNd“®¢)$2This is the network address you want checked. The °dONLNd
  6895. ®ù*
  6896. 1format of theAddress is the same as AddrBlock as °dONLNd>®"fl*
  6897. defined in °dONLNdIfl"˝)7Inside°dONLNdO˝") °dONLNdP"/)    Macintosh°dONLNdY/"u)- II, page 281:°dONLNdk+Ñ6L(R¢(Bytes 2 & 3 (High Word) - Network Number°dONLNdó5Ñ@Ë*
  6898. Byte 1 - Node Number°dONLNdØ?ÑJ)*
  6899. !Byte 0 (Low Byte) - Socket Number
  6900. °dONLNd—Ual(~6 Result codes°dONLNdflU®aƒ)êtrue°dONLNd‰UÃaÇ)$network is still reachable°dONLNdaÑmß(ä¢false°dONLNdaÃmû)Hnetwork is no longer reachable°dONLNd'yÖ#(°66AppleTalk Transition Queue handlers written in Pascal °dONLNd]y#Ö⁄(°A#must implement glue code to use the°dONLNdÅÖëY(≠6
  6901. netValidProc.°dONLNd詵Ô*$#Cable Range Change Transition Event°dONLNd≥¬Œß*The Cable Range Transition, °dONLNdœ¡ßÕ%)èATTransCableChange
  6902.     °dONLNd·√%Œ,)~, 
  6903. °dONLNd„¬,Œ⁄)"event informs AppleTalk Transition°dONLNdŒ⁄¿(ˆ6YQueue processes that the cable range for the current network has changed. This can occur °dONLNd_Œ¿⁄⁄(ˆfiwhen°dONLNdd⁄Ê(6:a router is first seen, when the last router ages out, or °dONLNdû⁄Ê⁄)ˇ&when an RTMP broadcast packet is first    °dONLNd≈ÊÚ°(6received with a cable 
  6904. °dONLNd€ʰÚ⁄)â3range that is different from the current range. The°dONLNdÚ˛ñ(6ATTransCableChange°dONLNd!ÛñˇO)~% event is implemented beginning with °dONLNdFÛOˇ⁄)πAppleTalk version 57. Most°dONLNdaˇ à('6applications should not °dONLNdyˇà ⁄)pFneed to process this event. With version 57 present, this event can be°dONLNd¿ (364expected in system software version 6.0.5 and later.
  6905. °dONLNdı#/œ*!The ATTransCableChange Transition
  6906. °dONLNd    :FR*@From Assembly language, the stack upon calling looks as follows: ¡4¡˘
  6907. *t24)
  6908.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ^◊#ˇ ˇˇˇˇ#◊ 
  6909. IR,Times
  6910. .+Z-Developer Support Center(-Á January 1993 /X/,
  6911. Courier°dONLNd<)l(EZATQEvent°dONLNd    Ñ)®)HRECORD°dONLNd∫)¿)60°dONLNd(<4x(PZ
  6912. ReturnAddr°dONLNd(Ñ4ú)HDS.L°dONLNd#(∫4¿)61°dONLNd%(Ã4>); address of caller°dONLNd93<?l([ZtheEvent°dONLNdB3Ñ?ú)HDS.L°dONLNdG3∫?¿)61°dONLNdI3Ã?§)$; = 'rnge'; ID of ATTransCableChange°dONLNdn><JN(fZaqe°dONLNdr>ÑJú)HDS.L°dONLNdw>∫J¿)61°dONLNdy>ÃJ\); pointer to task record°dONLNdíI<Uf(qZinfoPtr°dONLNdöIÑUú)HDS.L°dONLNdüI∫U¿)61°dONLNd°IÃU»)*; pointer to the TNetworkTransition record°dONLNdÕTÑ`ú(|¢ENDR
  6913. °dONLNd“l<xQ(îZThe °dONLNd÷kQwû) TNewCRTrans
  6914.     °dONLNd·mûx†)M 
  6915. °dONLNd‚l†x@)"record block is passed as follows:
  6916. °dONLNdÑ<ê~(¨Z TNewCRTrans°dONLNdÑÑê®)HRECORD°dONLNdÑ∫ê¿)60°dONLNdè<õx(∑Z
  6917. newCableLo°dONLNd%èÑõú)HDS.W°dONLNd*è∫õ¿)61°dONLNd,èÃõ™)%; the new Cable Lo received from RTMP°dONLNdRö<¶x(¬Z
  6918. newCableHi°dONLNd]öѶú)HDS.W°dONLNdbö∫¶¿)61°dONLNddöö™)%; the new Cable Hi received from RTMP°dONLNdã•ѱú(Õ¢ENDR
  6919. °dONLNdêº<».(‰Z.The cable range is a range of network numbers °dONLNdæº.»˛)Ú'starting from the lowest network number°dONLNdÊ»<‘@(Z0through the highest network number defined by a °dONLNd»@‘˛(^#seed router for a network. All node°dONLNd:‘<‡Û(¸Z%addresses acquired on a network must °dONLNd_‘Û‡˛)∑5have a network number within the defined cable range.°dONLNdï‡<Ï„(ZSFor nonextended networks, the lowest and the highest network numbers are the same. °dONLNdˇ„Ï˛(If the°dONLNdÔÏ<¯4(Z4cable range on the network changes, for example, if °dONLNd#Ï4¯˛)¯(the router on the network goes down, the°dONLNdL¯<—( ZVCable Range Change event will be issued with the parameters described earlier in this °dONLNd¢¯—˛( Ô    Technical°dONLNd¨<W(,ZNote.°dONLNd≤<(º*RAfter receiving the event, a multinode application should use the new cable range °dONLNdº(˛(D⁄to check if all°dONLNd(<4≤(PZOthe multinodes it obtained prior to the event are still valid. For the invalid °dONLNdc(≤4˛(P–multinodes, the°dONLNds5<Aï(]Zapplication should °dONLNdÜ5ïAfl)Yissue the .MPP
  6920. °dONLNdî5flA„)J 
  6921. °dONLNdï4„@))
  6922. RemoveNode°dONLNdü5)A˛)F. control call to get rid of invalid nodes. The°dONLNdŒB<N[(jZ.MPP °dONLNd”A[Mì)AddNode °dONLNd€BìNê)86control call can be issued immediately after removing °dONLNdBêN˛)˝invalid nodes to obtain°dONLNd)N<Z§(vZnew valid multinodes °dONLNd>N§Z˛)hEin the new cable range. This Cable Range Change Transition event will°dONLNdÑZ<f˜(ÇZ'be issued only during system task time.°dONLNd¨r<~*!The Speed Change Transition Event°dONLNdŒã<óR*The °dONLNd“äRñ–)ATTransSpeedChange°dONLNd‰ã–ó%)~ Transition event °dONLNdˆã%ó˛)U+is defined for applications that change CPU°dONLNd"ó<£+(øZ2speed without rebooting, to notify time-dependent °dONLNdTó+£˛)Ô+processes that such change has taken place.°dONLNdÄ£<ØÈ(ÀZWSuch speed change occurs when altering the cache states on the 68030 or 68040 CPUs, or °dONLNd◊£ÈØ˛(Àwith°dONLNd‹Ø<ª≈(◊Zthird- party accelerator cards °dONLNd˚Ø≈ª˛)â@that allow speed changes on the fly via a cdev. Any process that°dONLNd<º<»(‰Z.alters the effective CPU speed should use the °dONLNdjª«M)‡ATEvent°dONLNdqºM»˛)1$ to notify processes of this change.°dONLNdñ…<’m(ÒZ
  6923. Issue the °dONLNd†»m‘Ù)1ATTransSpeedChange °dONLNd≥…Ù’)áevent °dONLNdπ…’+)only°dONLNdΩ…+’?) at °dONLNd¡»?‘Ö)
  6924. SystemTask°dONLNdÀ…Ö’˛)F time! Any process that°dONLNd„’<·⁄(˝ZKdepends on changes to the CPU speed should watch for this event. The Speed °dONLNd.’⁄·˛(˝¯Change°dONLNd5·<ÌC(    Z8Transition event is issued only during system task time.°dONLNdn˘<é*=One time-dependent code module is LocalTalk, whose low-level °dONLNd´˘é˛(!¨timer values must be°dONLNd¿<§(-ZLrecalculated when the CPU speed changes. Note that altering the cache state °dONLNd     §˛(-¬on the 68030 does°dONLNd    <¯(9Z'not affect LocalTalk; however doing so °dONLNd    E¯˛)º5on the 68040 does affect LocalTalk timers. This event°dONLNd    {<)ù(EZmust be sent by any °dONLNd    èù)˛)aJapplication that toggles caching on the 68040 processor on the fly. If the°dONLNd    ⁄)<5Y(QZ:cache is toggled and LocalTalk is not notified, a loss of °dONLNd
  6925. )Y5˛(Qw!network connection will result if°dONLNd
  6926. 65<Aı(]ZRLocalTalk is the current network connection. Note that only LocalTalk implemented °dONLNd
  6927. à5ıA˛(]in°dONLNd
  6928. ãA<M(iZ)AppleTalk version 57 or later recognizes °dONLNd
  6929. ¥AM˛)»0the Speed Change Transition event. Contact Apple°dONLNd
  6930. ÂM<YC(uZ6Software Licensing for licensing AppleTalk version 57.°dONLNd e<q$*+Regarding LocalTalk on the Macintosh Plus, °dONLNd Ge$q˛)Ë'the timing values are hard-coded in ROM°dONLNd oq<}    (ôZ(regardless of the CPU speed. Vendors of °dONLNd óq    }˛)Õ0accelerators for Macintosh Plus computers should°dONLNd »}<âà(•ZBcontact DTS for information on how to make LocalTalk work for you. ¡X¡
  6931. *1(NW 13 - AppleTalk: The Rest of the Story(÷˙25)
  6932.  of 61(ÏZM.NW.AppleTalk2ˇÄ◊#ˇ ˇˇˇˇ#◊ 
  6933. IR,Times
  6934. .+6-Macintosh Technical Notes /4/˘°dONLNd)œ*!The ATTransSpeedChange Transition
  6935. °dONLNd"4@R*@From Assembly language, the stack upon calling looks as follows:,
  6936. Courier
  6937. °dONLNdcO[H*ATQEvent°dONLNdlO`[Ñ)HRECORD°dONLNdsO®[Æ)H0°dONLNdvZfT(Ç6
  6938. ReturnAddr°dONLNdÅZ`fx)HDS.L°dONLNdÜZÑfä)$1°dONLNdàZ®f)$; address of caller°dONLNdúeqH(ç6theEvent°dONLNd•e`qx)HDS.L°dONLNd™eÑqä)$1°dONLNd¨e®qÄ)$$; = 'sped'; ID of ATTransSpeedChange°dONLNd—p|*(ò6aqe°dONLNd’p`|x)HDS.L°dONLNd⁄pÑ|ä)$1°dONLNd‹p®|8)$; pointer to task record°dONLNd˜{`áx(£~ENDR
  6939. °dONLNd¸ìü”(ª6%To notify LocalTalk that a change in °dONLNd!ì”ü©)ª)processor speed has taken place, use the °dONLNdJí©û⁄)÷ATEvent°dONLNdR†¨N(»6 procedure. °dONLNd]†N¨d)6Pass°dONLNdaüd´Í) ATTransSpeedChange°dONLNdt†Í¨)Ü as the °dONLNd|ü´9)$event °dONLNddž9¨⁄)+"parameter and a nil pointer as the°dONLNd•¨∏R(’6infoPtr °dONLNd≠≠Rπ©):Cparameter. This event must be issued only at system task time. The °dONLNd¨©∏⁄(’«ATEvent°dONLNd¯π≈(·62procedure is implemented as a glue routine in MPW °dONLNd*π≈⁄)˜*3.2 or greater. The following line of code°dONLNdU≈—Ø(Ì6!demonstrates notification of the 
  6940. °dONLNdv≈Ø—)óATTransSpeedChange
  6941. °dONLNdà≈—;)l event.
  6942. °dONLNdê›È(6'     ATEvent (ATTransSpeedChange, nil);
  6943. °dONLNd∏Ù0*-Sample Pascal Source to LAPMgrExists Function°dONLNdÊ ∞*RIt is important to check whether the LAP Manager exists before making LAP Manager °dONLNd8 ∞⁄(4Œ
  6944. calls like°dONLNdC$W(A6    LAPAddATQ°dONLNdLW%Ä)?:. The LAP Manager is implemented beginning with AppleTalk °dONLNdÜÄ%⁄(Aûversion 53. Rather°dONLNdô&2æ(N6!than check the low-memory global °dONLNd∫%æ1˝)¶    LAPMgrPtr°dONLNd√&˝2Ö)? , it is preferable to check for °dONLNd„&Ö2⁄)àits existence from°dONLNdˆ2>l(Z6Ha higher level. The following Pascal source demonstrates this technique:
  6945.     °dONLNd?JU«*#FUNCTION GestaltAvailable: Boolean;°dONLNdcT_1*
  6946. CONST°dONLNdj^<ië+$
  6947. _Gestalt = $A1AD;°dONLNd|hs1(è6BEGIN°dONLNdÉr<}+$
  6948. ,GestaltAvailable := TrapAvailable(_Gestalt);°dONLNd±|<áü*
  6949. G{ TrapAvailable is documented in Inside Macintosh Volume VI, page 3-8 }°dONLNd˘Üë,(≠6END;°dONLNd˛§Ø«*#FUNCTION AppleTalkVersion: Integer;°dONLNd"Æπ1*
  6950. CONST°dONLNd)∏<√"+$
  6951. .versionRequested = 1; { version of SysEnvRec }°dONLNdX¬Õ'(È6VAR°dONLNd]Ã<◊å+$
  6952. refNum: INTEGER;°dONLNdo÷<·ë*
  6953. world: SysEnvRec;°dONLNdLJ<Îå*
  6954. attrib: LONGINT;°dONLNdìÍı1(6BEGIN°dONLNdöÙ<ˇ™+$
  6955. AppleTalkVersion := 0;°dONLNd±ÙÃˇS)ê{ default to no AppleTalk }°dONLNdŒ˛<    (%Z*IF OpenDriver('.MPP', refNum) = noErr THEN°dONLNd˘˛    •)ÿ{ open the AppleTalk driver }°dONLNd`ÿ(/~IF GestaltAvailable THEN°dONLNd4`y*
  6956. BEGIN°dONLNd=Ñ'¶+$
  6957. :IF (Gestalt(gestaltAppleTalkVersion, attrib) = noErr) THEN°dONLNd|&®1Ñ+$
  6958. ,AppleTalkVersion := BAND(attrib, $000000FF);°dONLNd´0`;o(W~END°dONLNd±:`Et*
  6959. ELSE°dONLNd∂:ÑE∫)$>{ Gestalt or gestaltAppleTalkVersion selector isn't available.°dONLNdıDO(k6}°dONLNd˙NÑYà+l
  6960. 4IF SysEnvirons(versionRequested, world) = noErr THEN°dONLNd3X®cp+$
  6961. (AppleTalkVersion := world.atDrvrVersNum;°dONLNd\bm,(â6END;°dONLNdaÄã≥*FUNCTION LAPMgrExists: Boolean;°dONLNdÅäï1*
  6962. BEGIN ¡4¡˘
  6963. *%26)
  6964.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ¶◊#ˇ ˇˇˇˇ#◊ 
  6965. IR,Times
  6966. .+Z-Developer Support Center(-Á January 1993 /X/,
  6967. Courier
  6968.     °dONLNd`(Ç(D~:{ AppleTalk phase 2 is in AppleTalk version 53 and later }°dONLNd<'`2-*
  6969. )LAPMgrExists := (AppleTalkVersion >= 53);°dONLNdf1<<P(XZEND;
  6970. °dONLNdkG<S>**Sample AppleTalk Transition Queue Function°dONLNdñ_<kë*BA sample AppleTalk Transition Queue function has been implemented °dONLNdÿ_ëk˛(áØin both C and Pascal.°dONLNdÓk<wÄ(ìZCThese samples have been submitted as snippet code to appear on the °dONLNd1kÄwΔ(ìû
  6971. Developer CD °dONLNd>kΔw„)FSeries°dONLNdDk„w˛) disc.°dONLNdKw<ÉÛ(üZ$Since Transition Queue handlers are °dONLNdowÛɲ)∑4called with a C-style stack frame, the Pascal sample°dONLNd§É<èÀ(´Zincludes the necessary C glue.
  6972. °dONLNd√õ<ß:*/Sample AppleTalk Transition Queue Function in C
  6973. °dONLNdÛ≤<æÊ*SThe following is a sample AppleTalk Transition Queue handler for C programmers. To °dONLNdF≤Êæ˛(⁄place°dONLNdLø<À(ÁZ/the handler in the AppleTalk Transition Queue, °dONLNd{øÀô)‡define a structure of type °dONLNdñæô fl)}
  6974. myATQEntry°dONLNd†øflÀ˛)F in the    °dONLNd®À<◊=(ÛZ)main body of the application. Assign the 
  6975. °dONLNd—À=◊˛(Û[ SampleTransQueue function to the°dONLNdÚ◊<„¡(ZmyATQEntry.CallAddr°dONLNdÿ¡‰)Ö field. Use the °dONLNd◊„p)FLAPAddATQFixed °dONLNd$ÿp‰ö)i    function °dONLNd-ÿö‰˛)*to add the handler to    °dONLNdC‰<˝( Z the AppleTalk Transition Queue. 
  6976. °dONLNdc‰˝˛)¡'Remember to remove the handler with the°dONLNdã<¸û(ZLAPRmvATQFixed°dONLNdôÒû˝[)b* function before quitting the application.°dONLNdƒ    <p(1ZWarning:°dONLNdà   ps)4 °dONLNdŒ    Ñ)The System 7 Tuner extension °dONLNdΠ   ⁄)ò'will not load AppleTalk resources if it°dONLNdÑ!(=¢!detects that AppleTalk is off at °dONLNd4!⁄)í'boot time. Remember to check the result°dONLNd\"Ñ.Ø(J¢    from the °dONLNde!Ø-)+LAPAddATQFixed°dONLNds".{)b function to determine °dONLNdä"{.⁄)jwhether the handler°dONLNdû.Ñ:(V¢was installed successfully.°dONLNdªF<R0(nZ/The following code was written with MPW C v3.2:
  6977.     °dONLNdÎ^<i§*H/*----------------------------------------------------------------------°dONLNd4h<s†*
  6978.   file: TransQueue.h°dONLNdIr<}§*
  6979. H----------------------------------------------------------------------*/°dONLNdïÜ<ë™*#include <AppleTalk.h>°dONLNd¨ö<•F*/*°dONLNdا<ج*
  6980. N *  Transition Queue routines are designed with C calling conventions in mind.°dONLNd˛Æ<π÷*
  6981. R *  They are passed parameters with a C-style stack and return values are expected°dONLNdQ∏<√π*
  6982.  *  to be in register D0.°dONLNdk¬<ÕK*
  6983.  */°dONLNdo÷<·õ*#define ATTransOpen°dONLNdÖ÷·ı)¥0°dONLNdá÷·Ç)$/* .MPP just opened */°dONLNdû‡<Ά(Z#define ATTransClose°dONLNdµ‡Îı)¥2°dONLNd∑‡Î})$/* .MPP is closing */°dONLNdÕÍ<ı¥(Z#define ATTransClosePrep°dONLNdÁÍıı)¥3°dONLNdÈÍıõ)$/* OK for .MPP to close? */°dONLNdÙ<ˇæ(Z#define ATTransCancelClose°dONLNd!Ùˇı)¥4°dONLNd#Ùˇ†)$/* .MPP close was canceled*/°dONLNd@˛<    ‹(%Z #define ATTransNetworkTransition°dONLNda˛    ı)¥5°dONLNdc˛    æ)$"/* .MPP Network ADEV transition */°dONLNdÜ<·(/Z!#define ATTransNameChangeTellTask°dONLNd®ı)¥6°dONLNd™Ø)$/* Flagship name is changing */°dONLNd <‹(9Z #define ATTransNameChangeAskTask°dONLNdÎı)¥7°dONLNdÌ¥)$ /* OK to change Flagship name */°dONLNd<'◊(CZ#define ATTransCancelNameChange°dONLNd.'ı)¥8°dONLNd0'◊)$'/* Flagship name change was canceled */°dONLNdX&<1æ(MZ#define ATTransCableChange°dONLNdt&1)¥'rnge'°dONLNd{&1Õ)$%/* Cable Range Change has occurred */°dONLNd°0<;æ(WZ#define ATTransSpeedChange°dONLNdΩ0;)¥'sped'°dONLNdƒ0;·)$)/* Change in processor speed has occurred°dONLNdÙ:E-*
  6984.    */°dONLNd˙N<Y§(uZH/*----------------------------------------------------------------------°dONLNd    EXÑc +H
  6985. NBP Name Change Info record°dONLNd    ab<m§(âZH----------------------------------------------------------------------*/ ¡X¡
  6986. *M(NW 13 - AppleTalk: The Rest of the Story(÷˙27)
  6987.  of 61(ÏZM.NW.AppleTalk2ˇL◊#ˇ ˇˇˇˇ#◊ 
  6988. IR,Times
  6989. .+6-Macintosh Technical Notes /4/˘,
  6990. Courier
  6991.     °dONLNd(≥*typedef struct NameChangeInfo {°dONLNd!'<2Z+$
  6992. Str32 °dONLNd('`2í)$
  6993. newObjStr;°dONLNd3'®2)H/* new NBP name */°dONLNdG1<<K(XZPtr°dONLNdK1`<y)$name;°dONLNdR1®<∂)H6/* Ptr to location to place a pointer to Pascal string°dONLNdç;®F–*
  6994.    of */°dONLNdöE®Pz*
  6995. */* name of process that NAK'd the event */°dONLNd≈OZ(v6}°dONLNd»Y<d,+$
  6996. 0NameChangeInfo, *NameChangePtr, **NameChangeHdl;°dONLNd˘mxÄ(î6H/*----------------------------------------------------------------------°dONLNdDw`Lj+H
  6997. Network Transition Info Record°dONLNdcÅåÄ(®6H----------------------------------------------------------------------*/°dONLNd¨ï†«*#typedef struct TNetworkTransition {°dONLNd—ü<™K+$
  6998. Ptr°dONLNd÷üÑ™¨)Hprivate;°dONLNd‡ü™ö)l"/* pointer to private structure */°dONLNd©<¥_(–ZProcPtr°dONLNd ©Ñ¥≈)H
  6999. netValidProc;°dONLNd©¥ï)l!/* pointer to network validation °dONLNdB≥Ãæ:(⁄Í          procedure */°dONLNdZΩ<»d(‰ZBoolean °dONLNdcΩÑ»‘)HnewConnectivity;°dONLNdtΩ»w)l/* true = new connection */°dONLNdñ«“ê*
  7000.  /* false = loss of connection */°dONLNd∑€Ê(6}°dONLNd∫Â<ï+$
  7001. ETNetworkTransition , *TNetworkTransitionPtr, **TNetworkTransitionHdl;°dONLNd˘;( 6typedef°dONLNd˘`ó)H pascal long°dONLNd˘®ù)H1(*NetworkTransitionProcPtr)(TNetworkTransitionPtr°dONLNdFO(*6 netTrans, \°dONLNdW
  7002. ÃD+¥
  7003.   unsigned long theNet);°dONLNdp!,Ä(H6H/*----------------------------------------------------------------------°dONLNdª+`6
  7004. +H
  7005. "Cable Range Transition Info Record°dONLNdfi5@Ä(\6H----------------------------------------------------------------------*/°dONLNd'?J§*
  7006. typedef struct TNewCRTrans {°dONLNdEI<TU+$
  7007. short°dONLNdKI`Tó)$ newCableLo;°dONLNdWI®Tu)H)/* the new Cable Lo received from RTMP */°dONLNdÇS<^U(zZshort°dONLNdàS`^ó)$ newCableHi;°dONLNdîS®^u)H)/* the new Cable Hi received from RTMP */°dONLNdæ]h(Ñ6}°dONLNd¡g<r,+$
  7008. 0TNewCRTrans , *TNewCRTransPtr, **TNewCRTransHdl;°dONLNdÚ{ÜÄ(¢6H/*----------------------------------------------------------------------°dONLNd=Ö`ê
  7009. +H
  7010. "AppleTalk Transition Queue Element°dONLNd`èöÄ(∂6H----------------------------------------------------------------------*/°dONLNd©ô§^*
  7011. typedef struct°dONLNd∏ôѧ¿)l myATQEntry {°dONLNdΔ£<ÆK( ZPtr°dONLNdÀ£ÑÆ¢)HqLink;°dONLNd”£ÃÆS)H/* -> next queue element */°dONLNd≠<∏U(‘Zshort°dONLNd˜≠Ñ∏¢)HqType;°dONLNdˇ≠Ã∏)H /* unused */°dONLNd
  7012. ∑<¬_(fiZProcPtr°dONLNd∑Ѭ±)H    CallAddr;°dONLNd∑ì])H/* -> transition procedure */°dONLNd>¡<ÃK(ËZPtr°dONLNdC¡Ñâ)Hglobs;°dONLNdK¡ÃÃl)H /* -> to user defined globals */°dONLNdlÀ÷(Ú6}°dONLNdo’<‡+$
  7013. ,myATQEntry, *myATQEntryPtr, **myATQEntryHdl;°dONLNdúÛ˛Ä(6H/*----------------------------------------------------------------------°dONLNd½|*
  7014.   file: TransQueue.c°dONLNd˙Ä*
  7015. H----------------------------------------------------------------------*/°dONLNdC&w*#include <Memory.h>°dONLNdW%0Ü*
  7016. #include <AppleTalk.h>°dONLNdn/:ã*
  7017. #include "TransQueue.h"°dONLNdÜCND*<long SampleTransQueue(long selector, myATQEntry *q, void *p)°dONLNd√MX*
  7018. {°dONLNdΔW<bP+$
  7019. long°dONLNdÕW®b±)l5returnVal = 0; /* return 0 for unrecognized events */°dONLNda<l}(àZ
  7020. NameChangePtr°dONLNdal@)¥myNameChangePtr;°dONLNd'k<vÇ(íZTNewCRTransPtr°dONLNd8kvE)¥myTNewCRTransPtr;°dONLNdJuÄ"(ú6  °dONLNdMu<Ä•)$TNetworkTransitionPtr°dONLNdduÄh)¥myTNetworkTransitionPtr;°dONLNd~<ä¥(¶ZNetworkTransitionProcPtr°dONLNdòä,)¥ myNTProcPtr;°dONLNd¶â<îi(∞Z    StringPtr°dONLNd≥âî')¥ newNamePtr; ¡4¡˘
  7021. (÷628)
  7022.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇt◊#ˇ ˇˇˇˇ#◊ 
  7023. IR,Times
  7024. .+Z-Developer Support Center(-Á January 1993 /X/,
  7025. Courier
  7026.     °dONLNd`(t(D~long°dONLNd    (U)¥
  7027. checkThisNet;°dONLNd'`2y(N~char °dONLNd"'2()¥**t;°dONLNd(1`<y(X~short°dONLNd21<})¥myCableLo, myCableHi;°dONLNdLO`Zj(v~/*°dONLNdPY`d‹*
  7028. L * This is the dispatch part of the routine. We'll check the selector passed°dONLNdûc`nØ*
  7029. C   into the task; its location is 4 bytes off the stack (selector).°dONLNd„m`xo*
  7030.  */°dONLNdËw`Ç∫*
  7031. switch(selector) {°dONLNd˝ÅÑåŸ+$
  7032. case ATTransOpen:°dONLNdã®ñ≤+$
  7033. /*°dONLNdﮆ„*
  7034. ? *  Someone has opened the .MPP driver. This is where one would°dONLNd[ü®™fi*
  7035. > * reset the application to its usual network state (that is, °dONLNdú©®¥œ*
  7036. ; * you could register your NBP name here). Always return 0.°dONLNd€≥®æ∑*
  7037.  */°dONLNd‚Ω®»Δ*
  7038. break;°dONLNdÔ—Ñ‹fi(¯¢case ATTransClose:°dONLNd€®Ê≤+$
  7039. /*°dONLNd ®fi*
  7040. > *  When this routine is called, .MPP is going to shut down no°dONLNdMÔ®˙„*
  7041. ? *  matter what we do. Handle that type of situation here (that°dONLNdê˘®¿*
  7042. 8 *  is, one could remove an NBP name and close down all °dONLNdîfi*
  7043. > *  sessions); 'p' will be nil. Return 0 to indicate no error.°dONLNd
  7044. ®∑*
  7045.  */°dONLNd®"Δ*
  7046. break;°dONLNd"+Ñ6Ú(R¢case ATTransClosePrep:°dONLNd<5®@≤+$
  7047. /*°dONLNdC?®J *
  7048. : *  This event gives us the chance to deny the closing of °dONLNdÄI®TW*
  7049. # *  AppleTalk if we want. Returning°dONLNd§I\Tfi)¥a value of 0 means it's OK°dONLNd¬S®^fi(zΔ> *  to close; nonzero indicates we'd rather not close at this °dONLNd]®h’*
  7050.      *  time.°dONLNdg®r≤*
  7051.  *°dONLNdq®|∂*
  7052. 6 *  With this event, the parameter 'p' actually means °dONLNdP{®Ü‘*
  7053. < *  something. 'p' in this event is a pointer to an address °dONLNdèÖ®êfi*
  7054. > *  that can hold a pointer to a string of our choosing. This °dONLNd–è®öŸ*
  7055. = *  string indicates to the user which task would rather not °dONLNdô®§fi*
  7056. > *  close. If you don't want AppleTalk to close, but you don't°dONLNdR£®Æfi*
  7057. > *  have a name to stick in there, you MUST place a nil value °dONLNdì≠®∏*
  7058.  *  in there instead.°dONLNd¨∑®¬≤*
  7059.  *°dONLNd≤¡®Ãfi*
  7060. > *  (We're doing this all locally to this case because it's C °dONLNdÛÀ®÷/*
  7061.  *   and we can, so there.)°dONLNd’®‡∑*
  7062.  */°dONLNdfl®Íé*
  7063. .newNamePtr = (StringPtr)NewPtr(sizeof(Str32));°dONLNdOÛ®˛≤*/*°dONLNdU˝®a*
  7064. % *  Assume Ptr allocation successful.°dONLNd~®∑*
  7065.  */°dONLNdâ®&9*newNamePtr = "\pBanana Mail";°dONLNdß\&fi)¥/* This will either be an °dONLNdƒ%®0fi(LΔ>Ax reference or PC relative depending on compiler and options.°dONLNd/®:≤*
  7066. */°dONLNdC®N≤*/*°dONLNdM®X‘*
  7067. < *  Get a new reference to the address we were passed (in a °dONLNdWW®b*
  7068.  *  form we can use).°dONLNdqa®l∑*
  7069.  */°dONLNdxk®v¯*
  7070. t = (char **) p;°dONLNdåu®Ä≤*
  7071. /*°dONLNdì®äŸ*
  7072. = *  Place the address of our string into the address we were °dONLNd”â®îfl*
  7073.  *  passed. ¡X¡
  7074. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙29)
  7075.  of 61(ÏZM.NW.AppleTalk2ˇ T◊#ˇ ˇˇˇˇ#◊ 
  7076. IR,Times
  7077. .+6-Macintosh Technical Notes /4/˘,
  7078. Courier
  7079.     °dONLNdÑ(ì+l */°dONLNd'Ñ2¸*
  7080. *t = (char *)newNamePtr;°dONLNd#;ÑFé*/*°dONLNd*EÑP∫*
  7081. > *  Return a nonzero value so that AppleTalk knows we'd rather°dONLNdlOÑZ *
  7082.  *  not close.°dONLNd~YÑdì*
  7083.  */°dONLNdÖcÑn *
  7084. returnVal = 1;°dONLNdómÑxß*
  7085. break; °dONLNd©Å`åÿ(®~case ATTransCancelClose:°dONLNd≈ãÑñé+$
  7086. /*°dONLNdÀïцó*
  7087. 7 *  Just kidding, we didn't really want to cancel that °dONLNdüÑ™ú*
  7088. 8 *  AppleTalk closing after all. Reset all your network °dONLNdB©Ñ¥∞*
  7089. < *  activities that you have disabled here (if any). In our °dONLNdÅ≥ÑæÉ*
  7090. 3 *  case, we'll just fall through. 'p' will be nil.°dONLNdπΩÑ»¢*
  7091.     */°dONLNd√«Ñ“¢*
  7092. break;°dONLNd–€`ʈ(~case ATTransNetworkTransition:°dONLNdÚÂÑé+$
  7093. /*°dONLNd¯ÔÑ˙¶*
  7094. : *  A Remote AppleTalk connection has been made or broken.°dONLNd7˘Ñà*
  7095. 4 *  'p' is a pointer to a TNetworkTransition record.°dONLNdoÑË*
  7096.  *  Always return 0.°dONLNdá
  7097. Ñì*
  7098.  */°dONLNdéÑ"É*
  7099. 3myTNetworkTransitionPtr = (TNetworkTransitionPtr)p;°dONLNd≈!Ñ,é*
  7100. /*°dONLNdÀ+Ñ6í*
  7101. 6 *  Check newConnectivity element to determine whether°dONLNd5Ñ@e*
  7102. - *  Remote Access is coming up or going down.°dONLNd6?ÑJì*
  7103.  */°dONLNd=IÑTo*
  7104. /if (myTNetworkTransitionPtr->newConnectivity) {°dONLNdqS®^≤+$
  7105. /*°dONLNdx]®h *
  7106.  * Have a new connection°dONLNdïg®r∑*
  7107.  */°dONLNdúqÑ|â(ò¢}°dONLNd°{ÑÜ¢*
  7108. else {°dONLNd¨Ö®ê≤+$
  7109. /*°dONLNd≥è®öò*
  7110. 0 * Determine which network addresses need to be °dONLNdËô®§¢*
  7111. 2 * validated and assign the value to checkThisNet.°dONLNd£®Æ¡*
  7112.    */°dONLNd)≠®∏¨*
  7113. 4checkThisNet = 0x1234FD80;  /* network 0x1234, node °dONLNda∑®¬ *
  7114. 0xFD, socket 0x80 */°dONLNdz¡®ÃÈ*
  7115.  
  7116. myNTProcPtr =°dONLNdàÀ÷X(Ú6@(NetworkTransitionProcPtr)myTNetworkTransitionPtr->netValidProc;°dONLNdÕ’®‡Ñ+ê
  7117. ,if ((*myNTProcPtr)(myTNetworkTransitionPtr, °dONLNd˛fl®ͯ*
  7118. checkThisNet)) {°dONLNdÈÃÙ÷+$
  7119. /*°dONLNdÛÃ˛N*
  7120.  * Network is still valid.°dONLNd=˝Ã€*
  7121.  */°dONLNdE®≠(.Δ}°dONLNdK®Δ*
  7122. else {°dONLNdWÃ&÷+$
  7123. /*°dONLNd`%Ã0b*
  7124.  * Network is no longer valid.°dONLNdÑ/Ã:€*
  7125.  */°dONLNdå9®D≠(`Δ}°dONLNdëCÑNâ(j¢}°dONLNdñMÑX¢*
  7126. break; ¡4¡˘
  7127. (÷630)
  7128.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇΔ◊#ˇ ˇˇˇˇ#◊ 
  7129. IR,Times
  7130. .+Z-Developer Support Center(-Á January 1993 /X/,
  7131. Courier
  7132.     °dONLNdÑ((D¢case ATTransNameChangeTellTask:°dONLNd#'®2≤+$
  7133. /*°dONLNd)1®<fi*
  7134. > *  Someone is changing the Flagship name and there is nothing°dONLNdk;®F„*
  7135. ? *  we can do. The parameter 'p' is a pointer to a Pascal-style°dONLNdÆE®Pì*
  7136. / *  string that holds the new Flagship name. */°dONLNd·O®Z/*
  7137. newNamePtr = (StringPtr) p;°dONLNdc®n≤*/*°dONLNdm®x„*
  7138. ? *  You should deregister any previously registered NBP entries°dONLNdIw®Ç±*
  7139. 5 *  under the 'old' Flagship name. Always return 0.*/°dONLNdÇÅ®åΔ*
  7140. break;°dONLNdèïц(º¢case ATTransNameChangeAskTask:°dONLNd±ü®™≤+$
  7141. /*°dONLNd∑©®¥é*
  7142. . *  Someone is messing with the Flagship name.°dONLNdÍ≥®æ∂*
  7143. 6 *  With this event, the parameter 'p' actually means °dONLNd$Ω®»„*
  7144. ? *  something. 'p' is a pointer to a NameChangeInfo record. The°dONLNdg«®“œ*
  7145. ; *  newObjStr field contains the new Flagship name. Try to °dONLNd•—®‹ª*
  7146. 7 *  register a new entity using the new Flagship name. °dONLNd‡€®Ê„*
  7147. ? *  Returning a value of 0 means it's OK to change the Flagship°dONLNd#®’*
  7148.      *  name.°dONLNd0Ô®˙∑*
  7149.  */°dONLNd7˘®W*
  7150. #myNameChangePtr = (NameChangePtr)p;°dONLNd^
  7151. ®≤*/*°dONLNdd®"fi*
  7152. > *  If the NBPRegister is unsuccessful, return the error. You °dONLNd•!®,Ÿ*
  7153. = *  must also set p->name pointer with a pointer to a Pascal-°dONLNdÂ+®6p*
  7154. ( *  style string of the process name. */°dONLNd5®@Δ*
  7155. break;°dONLNdIÑT(p¢case ATTransCancelNameChange:°dONLNd?S®^≤+$
  7156. /*°dONLNdE]®h‘*
  7157. < *  Just kidding, we didn't really want to change that name °dONLNdÑg®r≈*
  7158. 9 *  after all. Remove new NBP entry registered under the °dONLNd¿q®|Ÿ*
  7159. = *  ATTransNameChangeAskTask Transition. In our case,  we'll °dONLNd{®Üfi*
  7160. > *  just fall through. 'p' will be nil. Remember to return 0. °dONLNdAÖ®êΔ*
  7161.     */°dONLNdKè®öΔ*
  7162. break;°dONLNdT£ÑƸ( ¢case ATTransCableChange:°dONLNdp≠®∏≤+$
  7163. /*°dONLNdv∑®¬Ÿ*
  7164. = *  The cable range for the network has changed. The pointer °dONLNd∂¡®Ã *
  7165. : *  'p' points to a structure with the new network range. °dONLNdÛÀ®÷fi*
  7166. > *  (TNewCRTransPtr)p->newCableLo the lowest value of the new °dONLNd4’®‡„*
  7167. ? *  network range. (TNewCRTransPtr)p->newCableHi is the highest°dONLNdwfl®Ífi*
  7168. > *  value of the new network range. After handling this event,°dONLNdπÈ®Ù*
  7169.  *  always return 0. */°dONLNd‘Û®˛a*
  7170. %myTNewCRTransPtr = (TNewCRTransPtr)p;°dONLNd˝˝®u*
  7171. )myCableLo = myTNewCRTransPtr->newCableLo;°dONLNd*®u*
  7172. )myCableHi = myTNewCRTransPtr->newCableHi;°dONLNdW®Δ*
  7173. break;°dONLNd`%Ñ0¸(L¢case ATTransSpeedChange:°dONLNd|/®:≤+$
  7174. /*°dONLNdÇ9®D„*
  7175. ? *  The processor speed has changed. Only LocalTalk responds to°dONLNd≈C®Nœ*
  7176. ; *  this event. We demonstrate this event for completeness °dONLNdM®X9*
  7177.  *  only. Always return 0. */°dONLNd$W®bΔ*
  7178. break;°dONLNd-kÑv¨(í¢default:°dONLNd9u®Ä≤+$
  7179. /*°dONLNd?®äœ*
  7180. ; *  For future Transition Queue events (and yes, Virginia, °dONLNd}â®î/*
  7181.  *  there will be more). */ ¡X¡
  7182. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙31)
  7183.  of 61(ÏZM.NW.AppleTalk2ˇ
  7184. ◊#ˇ ˇˇˇˇ#◊ 
  7185. IR,Times
  7186. .+6-Macintosh Technical Notes /4/˘,
  7187. Courier
  7188.     °dONLNdÑ(¢+lbreak;°dONLNd'<2•(NZ} /* end of switch */°dONLNd!;<FF*/*°dONLNd&E<PF*
  7189.  *°dONLNd)E`PÁ)$return value in register D0°dONLNdGO<ZK(vZ */°dONLNdLY<dë*
  7190. return returnVal;°dONLNd^cn(ä6}
  7191. °dONLNd`yÖ-*4Sample AppleTalk Transition Queue Function in Pascal
  7192. °dONLNdïêúr*AThe following is a sample AppleTalk Transition Queue handler for °dONLNd÷êrú⁄(∏êPascal programmers.°dONLNdÍú®Ç(ƒ6FAppleTalk Transition Queue handlers are passed parameters using the C °dONLNd0úÇ®⁄(ƒ†parameter passing°dONLNdB®¥Ø(–6Xconvention. In addition, the 4-byte function result must be returned in register D0. To °dONLNdö®Ø¥⁄(–Õ    meet this°dONLNd§¥¿®(‹6Qrequirement, a C procedure is used to call the handler, then to place the 4-byte °dONLNdı¥®¿⁄(‹Δ result into°dONLNd¿Ã0(Ë6<register D0. The stub procedure listing follows the handler.°dONLNd?ÿ‰≥*KTo place the handler in the AppleTalk Transition Queue, define a structure °dONLNdäÿ≥‰⁄(—of type°dONLNdí‰^(
  7193. 6
  7194. myATQEntry°dONLNdúÂ^Òá)F in the °dONLNd§ÂáÒe)))main body of the application. Assign the °dONLNdÕ‰e“)fiCallTransQueue °dONLNd‹Â“Ò⁄)mC°dONLNdfiÚ˛j(6procedure to the °dONLNdÔÒj˝˜)RmyATQEntry.CallAddr °dONLNdÚ˜˛+)ç field. Use °dONLNdÚ+˛>)4the °dONLNdÒ>˝†)LAPAddATQFixed°dONLNd Ú†˛⁄)b  function to°dONLNd-˛
  7195. Ä(&6add the handler to the °dONLNdD˛Ä
  7196. ⁄)hCAppleTalk Transition Queue. Remember to remove the handler with the°dONLNdà
  7197. z(36LAPRmvATQFixed°dONLNdñ z7)b* function before quitting the application.°dONLNd¡#/L(K6Warning:°dONLNd…#L/h)4 The °dONLNdŒ#h/∂)@System 7 Tuner extension will not load AppleTalk resources if it°dONLNd/`;Ú(W~!detects that AppleTalk is off at °dONLNd0/Ú;∂)í'boot time. Remember to check the result°dONLNdX<`Hã(d~    from the °dONLNda;ãGÌ)+LAPAddATQFixed°dONLNdo<ÌHW)b function to determine °dONLNdÜ<WH∂)jwhether the handler°dONLNdöH`Tfi(p~was installed successfully.°dONLNd∑`lA(à6:The following code was written with MPW Pascal and C v3.2:
  7198.     °dONLNdÚxÉ≠*Q{********************************************************************************°dONLNdDÇç|*
  7199.   file: TransQueue.p°dONLNdYåó≠*
  7200. Q********************************************************************************}°dONLNd´†´h*UNIT TransQueue;°dONLNdº¥øE*    INTERFACE°dONLNdΔ»”Ù*,USES MemTypes, QuickDraw, OSIntF, AppleTalk;°dONLNdÛ‹Á1*CONST°dONLNd˘ÊÒè*
  7201. K(*  Comment the following 4 constants since they are already defined in the°dONLNdE˚c*
  7202. AppleTalk unit.°dONLNdV˙?*
  7203. ;    ATTransOpen                 =   0;  { .MPP is opening }°dONLNdí?*
  7204. ;    ATTransClose                =   2;  { .MPP is closing }°dONLNdŒ]*
  7205. A    ATTransClosePrep            =   3;  { OK for .MPP to close? }°dONLNd#g*
  7206. C    ATTransCancelClose          =   4;  { .MPP close was canceled }°dONLNdT"-"*
  7207. *)°dONLNdW,7Ä*
  7208. H    ATTransNetworkTransition    =   5;  { .MPP Network ADEV transition }°dONLNd†6Aq*
  7209. E    ATTransNameChangeTellTask   =   6;  { Flagship name is changing }°dONLNdÊ@Kv*
  7210. F    ATTransNameChangeAskTask    =   7;  { OK to change Flagship name }°dONLNd-JUû*
  7211. N    ATTransCancelNameChange     =   8;  { Flagship name change was canceled. }°dONLNd|T_®*
  7212. P    ATTransCableChange          =   'rnge'; { Cable Range Change has occurred. }°dONLNdÕ^iî*
  7213. L    ATTransSpeedChange          =   'sped'; { Change in processor speed has °dONLNd     hs6+ÿ
  7214.    occurred. } ¡4¡˘
  7215. (÷632)
  7216.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  7217. IR,Times
  7218. .+Z-Developer Support Center(-Á January 1993 /X/,
  7219. Courier
  7220.     °dONLNd<(ü(DZG{----------------------------------------------------------------------°dONLNdJ'Ñ2 +H
  7221. NBP Name Change Info record°dONLNdf1<<ü(XZG----------------------------------------------------------------------}°dONLNdÆE<PP*TYPE°dONLNd¥Y<dØ*NameChangeInfo = RECORD°dONLNdÕc`nç+$
  7222.     newObjStr°dONLNd◊c®n–)H: Str32;°dONLNd·cnd)l{ new NBP name }°dONLNdÛm`xt(î~name°dONLNd˘m®xΔ)H: Ptr;°dONLNdmx‹)l({ Ptr to location to place a pointer to °dONLNd0wÇx*
  7223.   Pascal string of }°dONLNdMÅ\åœ+H
  7224. { name of process that °dONLNdlã\ñª*
  7225.   NAK'd the event }°dONLNdÅï`†t(º~END;°dONLNdÜü<™‹(ΔZ NameChangePtr = ^NameChangeInfo;°dONLNdß©<¥◊*
  7226. NameChangeHdl = ^NameChangePtr;°dONLNd«Ω<»ü*G{----------------------------------------------------------------------°dONLNd«Ñ“+H
  7227. Network Transition Info Record°dONLNd0—<‹ü(¯ZG----------------------------------------------------------------------}°dONLNdxÂ<√*TNetworkTransition = RECORD°dONLNdïÔ`˙É+$
  7228. private°dONLNdûÔÃ˙Í)l: Ptr;°dONLNdßÔ8˙ÿ)l { pointer to private structure }°dONLNd…˘`ú( ~ netValidProc°dONLNd÷˘®⁄)H
  7229. : ProcPtr;°dONLNd·˘«)H+{ pointer to network validation procedure }°dONLNd`‚(*~newConnectivity : Boolean;°dONLNd)r)ê{ true = new connection, }°dONLNdK
  7230. 8”+H
  7231.  { false = loss of connection }°dONLNdl`"t(>~END;°dONLNdq+<6(RZ,TNetworkTransitionPtr = ^TNetworkTransition;°dONLNdû5<@'*
  7232. /TNetworkTransitionHdl = ^TNetworkTransitionPtr;°dONLNdŒI<Tö*F{ The netValidProc procedure has the following C interface. Note the }°dONLNdS<^‡*
  7233. T{ CallNetValidProc C function, which follows. The C Glue routine allows the Pascal }°dONLNdj]<h^*
  7234. :{ handler to make the call to the netValidProc function. }°dONLNd•q<|A*{°dONLNdß{<Üõ*
  7235. typedef pascal long°dONLNdª{®ÜŸ)l=(*NetworkTransitionProcPtr)(TNetworkTransitionPtr netTrans, \°dONLNd˛Öêh+H
  7236.   unsigned long theNet);°dONLNdè<öA(∂Z}°dONLNdô<§ü*
  7237. G{----------------------------------------------------------------------°dONLNdc£ÑÆ.+H
  7238. "Cable Range Transition Info Record°dONLNdÜ≠<∏ü(‘ZG----------------------------------------------------------------------}°dONLNdŒ∑<¬†*
  7239. TNewCRTrans = RECORD°dONLNd‰¡`Ãí+$
  7240.  
  7241. newCableLo°dONLNdÔ¡®Ã⁄)H
  7242. : INTEGER;°dONLNd˙¡Ã≥)H'{ the new Cable Lo received from RTMP }°dONLNd#À`÷í(Ú~
  7243. newCableHi°dONLNd.À®÷⁄)H
  7244. : INTEGER;°dONLNd9À÷≥)H'{ the new Cable Hi received from RTMP }°dONLNdb’`‡t(¸~END;°dONLNdgfl<Í“(ZTNewCRTransPtr = ^TNewCRTrans;°dONLNdÜÈ<Ù·*
  7245. !TNewCRTransHdl = ^TNewCRTransPtr;°dONLNd¨˝<ü*G{----------------------------------------------------------------------°dONLNdˆÑ.+H
  7246. "AppleTalk Transition Queue Element°dONLNd<ü(8ZG----------------------------------------------------------------------}°dONLNda<&õ*
  7247. myATQEntry = RECORD°dONLNdv%`0y+$
  7248. qlink°dONLNd}%®0Δ)H: Ptr;°dONLNdÜ%0ë)l{ -> next queue element }°dONLNd°/`:y(V~qType°dONLNd®/®:⁄)H
  7249. : INTEGER;°dONLNd≥/:")H
  7250. { unused }°dONLNdø9`Dà(`~CallAddr°dONLNd»9®D⁄)H
  7251. : ProcPtr;°dONLNd”9Dw)H{ -> transition procedure }°dONLNdC`Ny(j~globs°dONLNd˜C®NΔ)H: Ptr;°dONLNdˇCNÜ)H{ -> to user defined globals }°dONLNdM`Xt(t~END;°dONLNd$W<b»(~ZmyATQEntryPtr = ^myATQEntry;°dONLNdAa<l◊*
  7252. myATQEntryHdl = ^myATQEntryPtr;°dONLNda<ä6*2{---------------- Prototypes --------------------} ¡X¡
  7253. *0(NW 13 - AppleTalk: The Rest of the Story(÷˙33)
  7254.  of 61(ÏZM.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  7255. IR,Times
  7256. .+6-Macintosh Technical Notes /4/˘,
  7257. Courier
  7258.     °dONLNd(∑*SFUNCTION SampleTransQueue (selector :LONGINT; q :myATQEntryPtr;  p :Ptr) : LONGINT;°dONLNdT'2*
  7259. {°dONLNdV1<û*
  7260. N *  Transition Queue routines are designed with C calling conventions in mind.°dONLNd•;F≤*
  7261. R *  They are passed parameters with a C-style stack and return values are expected°dONLNd¯EPô*
  7262. M *  to be in register D0. Note that the CallTransQueue C glue routine is used°dONLNdFOZ®*
  7263. P *  to reverse the C-style stack to Pascal style before calling the handler. The°dONLNdóYdû*
  7264. N *  procedure CallTransQueue follows this listing. To install this Trans Queue°dONLNdÊcn£*
  7265. O *  handler, assign CallTransQueue to the CallAddr field, NOT SampleTransQueue.°dONLNd6mx"*
  7266.  }°dONLNd9ÅåÄ*HFUNCTION CallNetValidProc(p : ProcPtr; netTrans : TNetworkTransitionPtr;°dONLNdäãñ•+¸
  7267.  theNet : LONGINT) : LONGINT;°dONLNd©ï†(º6{°dONLNd´ü™g*
  7268. C *  CallNetValidProc is used to call the netValidProc passed in the°dONLNd©¥≠*
  7269. Q *  TNetworkTransition record. Since Pascal cannot call the ProcPtr directly, a C°dONLNdC≥æÖ*
  7270. I *  glue routine is used. This routine is defined following this listing.°dONLNdçΩ»"*
  7271.  }°dONLNdê€Ê^*IMPLEMENTATION°dONLNdüÔ˙∑*SFUNCTION SampleTransQueue (selector :LONGINT; q :myATQEntryPtr;  p :Ptr) : LONGINT;°dONLNdÛ'*VAR°dONLNd¯
  7272. <i+$
  7273.     returnVal°dONLNd
  7274. Ã˛)ê
  7275. : LONGINT;°dONLNd<"x(>Z myNameChgPtr°dONLNdÃ")ê: NameChangePtr;°dONLNd1!<,å(HZmyTNewCRTransPtr°dONLNdC!Ã,!)ê: TNewCRTransPtr;°dONLNdV+<6Ø(RZmyTNetworkTransitionPtr°dONLNdn+Ã6D)ê: TNetworkTransitionPtr;°dONLNdà5<@n(\Z
  7276. newNamePtr°dONLNdï5Ã@)ê : StringPtr;°dONLNd£?<JÇ(fZprocessNameHdl°dONLNd≥?ÃJ)ê: StringHandle;°dONLNdƒI<T†(pZmyCableLo, myCableHi°dONLNd⁄IÃT˛)ê
  7277. : INTEGER;°dONLNdÊS<^}(zZ
  7278. shortSelector°dONLNdˆSÃ^˛)ê
  7279. : INTEGER;°dONLNd]<hx(ÑZ checkThisNet°dONLNdgr1(é6BEGIN°dONLNdq<|å+$
  7280. returnVal := 0; °dONLNd-q|§)¥${ return 0 for unrecognized events )°dONLNdS{<ÜA(¢Z{°dONLNdVÖ<êΩ*
  7281. M *  This is the dispatch part of the routine. We'll check the selector passed°dONLNd•è<öê*
  7282. D *  into the task; its location is 4 bytes off the stack (selector).°dONLNdÎô<§F*
  7283.  }°dONLNdÔ£<ÆΩ*
  7284. MIF ((selector <= ATTransCancelNameChange) AND (selector >= ATTransOpen)) THEN°dONLNd>≠<∏A*
  7285. {°dONLNdA∑<¬Æ*
  7286. J *  Check whether a numeric selector is being used whose known values are °dONLNdå¡<ÃΩ*
  7287. M *  between 8 and 0 so that we can implement a CASE statement with an INTEGER°dONLNd€À<÷d*
  7288.  *  var.°dONLNdÂ’<‡F*
  7289.  }°dONLNdÈfl<ÍU*
  7290. BEGIN°dONLNdÒÈ`Ù‚+$
  7291. shortSelector := selector;°dONLNdÛ`˛…*
  7292. CASE shortSelector OF°dONLNd'˝Ñ¿+$
  7293. ATTransOpen:°dONLNd7Ñù*
  7294. BEGIN°dONLNdA®≠+$
  7295. {°dONLNdG®&∂*
  7296. 6 *  Someone has opened the .MPP driver. This is where °dONLNdÅ%®0ù*
  7297. 1 *  one would reset the application to its usual °dONLNd∑/®:ª*
  7298. 7 *  network state (that is, you could register your NBP°dONLNdÛ9®DH*
  7299.   *  name here). Always return 0.°dONLNdC®N≤*
  7300.  }°dONLNdMÑXò(t¢END;°dONLNd+aÑl≈*
  7301. ATTransClose:°dONLNd<kÑvù*
  7302. BEGIN°dONLNdFu®Ä≠+$
  7303. {°dONLNdL®ä∂*
  7304. 6 *  When this routine is called, .MPP is going to shut°dONLNdáâ®îß*
  7305. 3 *  down no matter what we do. Handle that type of  ¡4¡˘
  7306. (÷634)
  7307.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ
  7308. R◊#ˇ ˇˇˇˇ#◊ 
  7309. IR,Times
  7310. .+Z-Developer Support Center(-Á January 1993 /X/,
  7311. Courier
  7312.     °dONLNdÃ(’(DÍ5 *  situation here (that is, one could remove an NBP °dONLNd9'Ã2fl*
  7313. 7 *  name and close down all sessions). 'p' will be nil.°dONLNdu1Ã<v*
  7314. " *  Return 0 to indicate no error.°dONLNdú;ÃF÷*
  7315.  }°dONLNd¢E®Pº(lΔEND;°dONLNdØY®d˝*ATTransClosePrep:°dONLNdƒc®n¡*
  7316. BEGIN°dONLNdŒmÃx—+$
  7317. {°dONLNd‘wÃÇ⁄*
  7318. 6 *  This event gives us the chance to deny the closing°dONLNdÅÃå–*
  7319. 4 *  of AppleTalk IF we want. Returning a value of 0 °dONLNdGãÃñÀ*
  7320. 3 *  means it's OK to close; nonzero indicates we'd °dONLNd~ïÆ{*
  7321. # *  rather not close at this time.*°dONLNd¶üÙ⁄*
  7322. 6 *  With this event, the parameter 'p' actually means °dONLNd‡©Ã¥–*
  7323. 4 *  something. 'p' in this event is a pointer to an °dONLNd≥Ãæ⁄*
  7324. 6 *  address that can hold a pointer to a string of our°dONLNdSΩû⁄*
  7325. 6 *  choosing. This string indicates to the user which °dONLNdç«Ã“À*
  7326. 3 *  task would rather not close. If you don't want °dONLNdƒ—Ë’*
  7327. 5 *  AppleTalk to close, but you don't have a name to °dONLNd˝€ÃÊÀ*
  7328. 3 *  stick in there,  you MUST place a nil value in °dONLNd4ÂÃ&*
  7329.  *  there instead.°dONLNdKÔÃ˙÷*
  7330.  }°dONLNdT×*{°dONLNd[
  7331. Ã⁄*
  7332. 6 *  Get a new reference to the address we were passed °dONLNdïÃ"S*
  7333.  *  (in a form we can use).°dONLNdµ!Ã,⁄*
  7334. 6 *  (We're doing this all locally to this case because°dONLNd+Ã6:*
  7335.  *  we can, so there.)°dONLNd 5Ã@÷*
  7336.  }°dONLNd?ÃJ!*
  7337. processNameHdl :=°dONLNd$I<Tˇ(pZ'StringHandle(NewHandle(sizeof(Str32)));°dONLNdV]Ãh—+ê{°dONLNd\gÃrfl*
  7338. 7 *  Place the address of our string into the address we°dONLNdòqÃ|*
  7339.  *  were passed.°dONLNdÆ{ÃÜ÷*
  7340.  }°dONLNdµÖÃê&*
  7341.  := 'Banana Mail';°dONLNdÃèÃöb*
  7342. Ptr(p) := Ptr(processNameHdl);°dONLNdÙ£ÃÆ—*{°dONLNd˙≠Ã∏fl*
  7343. 7 *  Return a nonzero value so that AppleTalk knows we'd°dONLNd6∑ì5*
  7344.  *  rather not close.°dONLNdP¡ÃÃ÷*
  7345.  }°dONLNdWÀÃ÷*
  7346. returnVal := 1;°dONLNdj’®‡º(¸ΔEND;°dONLNdrÈ®Ù*ATTransCancelClose:°dONLNdâÛ®˛¡*
  7347. BEGIN°dONLNdì˝Ã—+$
  7348. {°dONLNdôÃ⁄*
  7349. 6 *  Just kidding, we didn't really want to cancel that°dONLNd‘Ãfl*
  7350. 7 *  AppleTalk closing after all. Reset all your network°dONLNdÃ&fl*
  7351. 7 *  activities that you have disabled here (IF any). In°dONLNdL%Ã0fl*
  7352. 7 *  our case, we'll just fall through. 'p' will be nil.°dONLNdâ/Ã:÷*
  7353.  }°dONLNdè9®Dº(`ΔEND;°dONLNdóM®X%*ATTransNetworkTransition:°dONLNd¥W®b¡*
  7354. BEGIN°dONLNdæaÃl—+$
  7355. {°dONLNdƒkÃvÀ*
  7356. 3 *  A Remote AppleTalk connection has been made or °dONLNd˚uÃÄ’*
  7357. 5 *  broken. 'p' is a pointer to a TNetworkTransition °dONLNd4ÃäX*
  7358.  *  record. Always return 0.°dONLNdUâÃî÷*
  7359.  } ¡X¡
  7360. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙35)
  7361.  of 61(ÏZM.NW.AppleTalk2ˇ B◊#ˇ ˇˇˇˇ#◊ 
  7362. IR,Times
  7363. .+6-Macintosh Technical Notes /4/˘,
  7364. Courier
  7365.     °dONLNd®(¨+ê4myTNetworkTransitionPtr := TNetworkTransitionPtr(p);°dONLNd9'®2≠*
  7366. {°dONLNd?1®<∂*
  7367. 6 *  Check newConnectivity element to determine whether°dONLNdz;®Fâ*
  7368. - *  Remote Access is coming up or going down.°dONLNd¨E®P≤*
  7369.  }°dONLNd≥O®Z¢*
  7370. 2if (myTNetworkTransitionPtr^.newConnectivity) THEN°dONLNdÎY®d¡*
  7371. BEGIN°dONLNdˆcÃn—+$
  7372. {°dONLNd˝mÃxI*
  7373.  * Have a new connection.°dONLNdwÃÇ÷*
  7374.  }°dONLNd#Å®å∑(®ΔEND°dONLNd+ã®ñº*
  7375. ELSE°dONLNd5ﮆ¡*
  7376. BEGIN°dONLNd@üÙ—+$
  7377. {°dONLNdG©Ã¥∑*
  7378. / * Determine which network addresses need to be°dONLNd|≥Ãæä*
  7379. & *  validated and assign the value to °dONLNd®Ωû!*
  7380.  *  checkThisNet.°dONLNdø«Ã“÷*
  7381.  }°dONLNd«—Ë≠*
  7382. -checkThisNet = $1234FD80;  /* network $1234, °dONLNd˘€ÃÊ?*
  7383. node $FD, socket $80 */°dONLNdÂÃ÷*
  7384. if°dONLNdÔ˙0(68(CallNetValidProc(myTNetworkTransitionPtr^.netValidProc,°dONLNdY˘ë+¸
  7385. myTNetworkTransitionPtr, °dONLNdzå*
  7386. checkThisNet) <> 0) THEN°dONLNdò
  7387. ÃÂ(4ÍBEGIN°dONLNd§"ı+$
  7388. {°dONLNd¨!,r*
  7389.  * Network is still valid.°dONLNdÕ+6˙*
  7390.  }°dONLNd’5Ã@€(\ÍEND°dONLNdfi?ÃJ‡*
  7391. ELSE°dONLNdËIÃTÂ*
  7392. BEGIN°dONLNdÙS^ı+$
  7393. {°dONLNd¸]hÜ*
  7394.  * Network is no longer valid.°dONLNd!gr˙*
  7395.  }°dONLNd)qÃ|‡(òÍEND;°dONLNd2{®ܺ(¢ΔEND;°dONLNd:ÖÑêò(¨¢END;°dONLNdBôѧ*ATTransNameChangeTellTask:°dONLNd`£ÑÆù*
  7396. BEGIN°dONLNdj≠®∏≠+$
  7397. {°dONLNdp∑®¬∂*
  7398. 6 *  Someone is changing the Flagship name and there is°dONLNd´¡®Ã∂*
  7399. 6 *  nothing we can do. The parameter 'p' is a pointer °dONLNdÂÀ®÷ò*
  7400. 0 *  to a Pascal-style string that holds the new °dONLNd’®‡*
  7401.  *  Flagship name.°dONLNd1fl®Í≠*
  7402. }°dONLNd7È®Ù4*
  7403. newNamePtr := StringPtr (p);°dONLNdX˝®≠*{°dONLNd^®ª*
  7404. 7 *  You should deregister any previously registered NBP°dONLNdö®¢*
  7405. 2 *  entries under the 'old' Flagship name. Always °dONLNd–®&È*
  7406.  
  7407.  *  return 0.°dONLNd‚%®0≤*
  7408.  }°dONLNdË/Ñ:ò(V¢END;°dONLNdCÑN*ATTransNameChangeAskTask:°dONLNd
  7409. MÑXù*
  7410. BEGIN°dONLNdW®b≠+$
  7411. {°dONLNda®lé*
  7412. . *  Someone is messing with the Flagship name.°dONLNdQk®v∂*
  7413. 6 *  With this event, the parameter 'p' actually means °dONLNdãu®Ä¨*
  7414. 4 *  something. 'p' is a pointer to a NameChangeInfo °dONLNd√®äù*
  7415. 1 *  record. The newObjStr field contains the new °dONLNd˘â®î∂*
  7416. 6 *  Flagship name. Try to register a new entity using  ¡4¡˘
  7417. (÷636)
  7418.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ
  7419. *◊#ˇ ˇˇˇˇ#◊ 
  7420. IR,Times
  7421. .+Z-Developer Support Center(-Á January 1993 /X/,
  7422. Courier
  7423.     °dONLNdÃ(fl(DÍ7 *  the new Flagship name. Returning a value of 0 means°dONLNd<'Ã2î*
  7424. ( *  it's OK to change the Flagship name.°dONLNdi1Ã<÷*
  7425.  }°dONLNdp;ÃFv*
  7426. "myNameChgPtr := NameChangePtr (p);°dONLNdóOÃZ—*{°dONLNdüYÃdÀ*
  7427. 3 *  If the NBPRegister is unsuccessful, return the °dONLNd÷cÃn–*
  7428. 4 *  error. You must also set p->name pointer with a °dONLNdmÃx®*
  7429. , *  pointer to a string of the process name.°dONLNd?wÃÇ÷*
  7430.  }°dONLNdEÅ®åº(®ΔEND;°dONLNdMﮆ *ATTransCancelNameChange:°dONLNdiü®™¡*
  7431. BEGIN°dONLNds©Ã¥—+$
  7432. {°dONLNdy≥Ãæ⁄*
  7433. 6 *  Just kidding, we didn't really want to cancel that°dONLNd¥Ωûº*
  7434. 0 *  name change after all. Remove new NBP entry °dONLNdȫÓÀ*
  7435. 3 *  registered under the  ATTransNameChangeAskTask °dONLNd —Ë⁄*
  7436. 6 *  Transition. 'p' will be nil. Remember to return 0.°dONLNd\€ÃÊ÷*
  7437.  }°dONLNdb®º( ΔEND;°dONLNdj˘®’*    OTHERWISE°dONLNdxÃ+$
  7438. returnVal := 0;°dONLNdå
  7439. ×*
  7440. {°dONLNdíÃ"º*
  7441. 0 *  Just in case some other numeric selector is °dONLNd«!Ã,*
  7442.  *  implemented.°dONLNd‹+Ã6÷*
  7443.  }°dONLNd·5Ñ@≈(\¢
  7444. END; { CASE }°dONLNd?`Jo(f~END°dONLNdıI`Ti*
  7445. 5ELSE IF (ResType(selector) = ATTransCableChange) THEN°dONLNd,S`^y*
  7446. BEGIN°dONLNd4]Ñhâ+$
  7447. {°dONLNd8gÑr…*
  7448. A *  The cable range for the network has changed. The pointer 'p' °dONLNd{qÑ|í*
  7449. 6 *  points to a structure with the new network range. °dONLNdµ{ÑÜ…*
  7450. A *  (TNewCRTransPtr)p->newCableLo is the lowest value of the new °dONLNd¯ÖÑê›*
  7451. E *  network range. (TNewCRTransPtr)p->newCableHi is the highest value°dONLNd@èÑö›*
  7452. E * of the new network range. After handling this event, always return°dONLNdàôѧ¢*
  7453.  *  0.°dONLNdë£ÑÆé*
  7454.  }°dONLNdñ≠Ñ∏B*
  7455. &myTNewCRTransPtr := TNewCRTransPtr(p);°dONLNdø∑ѬV*
  7456. *myCableLo := myTNewCRTransPtr^.newCableLo;°dONLNdÏ¡ÑÃV*
  7457. *myCableHi := myTNewCRTransPtr^.newCableHi;°dONLNdÀÑ÷œ*
  7458. returnVal := 0;°dONLNd*’`‡o(¸~END°dONLNd/fl`Íi*
  7459. 5ELSE IF (ResType(selector) = ATTransSpeedChange) THEN°dONLNdfÈ`Ùy*
  7460. BEGIN°dONLNdnÛÑ˛â+$
  7461. {°dONLNdr˝Ñ›*
  7462. E *  The processor speed has changed. Only LocalTalk responds to this °dONLNdπÑ”*
  7463. C *  event. We demonstrate this event for completeness only. Always °dONLNd˛Ñ≈*
  7464.  
  7465.  *  return 0.°dONLNdÑ&é*
  7466.  }°dONLNd%Ñ0‘*
  7467.  returnVal := 0;°dONLNd&/`:ó(V~ END; { IF }°dONLNd3C`Nˆ*SampleTransQueue := returnVal;°dONLNdRM<XP(tZEND;°dONLNdWa<l§*HFUNCTION CallNetValidProc(p : ProcPtr; netTrans : TNetworkTransitionPtr;°dONLNd®k8v…+¸
  7468.  theNet : LONGINT) : LONGINT;°dONLNdΔu<Äi(úZ    EXTERNAL;°dONLNd–â<îå*END. { of UNIT } ¡X¡
  7469. *&(NW 13 - AppleTalk: The Rest of the Story(÷˙37)
  7470.  of 61(ÏZM.NW.AppleTalk2ˇî◊#ˇ ˇˇˇˇ#◊ 
  7471. IR,Times
  7472. .+6-Macintosh Technical Notes /4/˘,
  7473. Courier
  7474.     °dONLNd1<≠*+Q/********************************************************************************°dONLNdR;Fc*
  7475.   file: CGlue.c°dONLNdbEP≠*
  7476. Q********************************************************************************/°dONLNd¥OZÜ*
  7477. #include <AppleTalk.h>°dONLNdÀcnÄ*H/*----------------------------------------------------------------------°dONLNdm`xˆ+H
  7478. Network Transition Info Record°dONLNd5wÇÄ(û6H----------------------------------------------------------------------*/°dONLNd~ãñ«*#typedef struct TNetworkTransition {°dONLNd£ï<†K+$
  7479. Ptr°dONLNd®ïц¨)Hprivate;°dONLNd≤ï†ö)l"/* pointer to private structure */°dONLNd÷ü<™_(ΔZProcPtr°dONLNdfiüÑ™≈)H
  7480. netValidProc;°dONLNdÌü™ï)l!/* pointer to network validation °dONLNd©¥;*
  7481.    procedure */°dONLNd&≥<æ_(⁄ZBoolean°dONLNd.≥Ñæ‘)HnewConnectivity;°dONLNd?≥æ|)l/* true = new connection, */°dONLNdbΩ»ê*
  7482.  /* false = loss of connection */°dONLNdÉ—‹(¯6}°dONLNdÜ€<Êï+$
  7483. ETNetworkTransition , *TNetworkTransitionPtr, **TNetworkTransitionHdl;°dONLNdÃÔ˙;(6typedef°dONLNd‘Ô`˙ó)H pascal long°dONLNd‡Ô®˙ù)H1(*NetworkTransitionProcPtr)(TNetworkTransitionPtr°dONLNd˘O( 6 netTrans, \°dONLNd#ÃD+¥
  7484.   unsigned long theNet);°dONLNd<"Ä(>6H/*----------------------------------------------------------------------°dONLNdá!`,
  7485. +H
  7486. "AppleTalk Transition Queue Element°dONLNd™+6Ä(R6H----------------------------------------------------------------------*/°dONLNdÛ5@^*
  7487. typedef struct°dONLNd5Ñ@¿)l myATQEntry {°dONLNd?<JK(fZPtr°dONLNd?ÑJ¢)HqLink;°dONLNd?ÃJS)H/* -> next queue element */°dONLNd:I<TU(pZshort°dONLNdAIÑT¢)HqType;°dONLNdIIÃT)H /* unused */°dONLNdWS<^_(zZProcPtr°dONLNd_SÑ^±)H    CallAddr;°dONLNdiSÃ^])H/* -> transition procedure */°dONLNdà]<hK(ÑZPtr°dONLNdç]Ñh¢)Hglobs;°dONLNdï]Ãhl)H /* -> to user defined globals */°dONLNd∂gr(é6}°dONLNdπq<|+$
  7488. ,myATQEntry, *myATQEntryPtr, **myATQEntryHdl;°dONLNdÊÖêÄ(¨6H/*----------------------------------------------------------------------°dONLNd1è`öí+H
  7489.  
  7490. Prototypes°dONLNd<ô§Ä(¿6H----------------------------------------------------------------------*/°dONLNdÖ£Æv*
  7491. Fpascal long  SampleTransQueue (long selector, myATQEntry *q, void *p);°dONLNdÃ≠∏?*
  7492. ;long CALLTRANSQUEUE(long selector, myATQEntry *q, void *p);°dONLNd∑¬Ä*
  7493. H/* Capitalize CALLTRANSQUEUE so that linker can match this entry with */°dONLNdQ¡ÃÜ*
  7494. /* the Pascal call. */°dONLNdhÀ÷î*
  7495. Lpascal long CallNetValidProc(ProcPtr p, TNetworkTransitionPtr netTrans, long°dONLNdµ’‡@*
  7496. theNet);°dONLNdæÛ˛:*:long CALLTRANSQUEUE(long selector, myATQEntry *q, void *p)°dONLNd˘˝£*
  7497. O/* CallTransQueue sets up the Pascal stack for the SampleTransQueue handler, */°dONLNdI«*
  7498. #/* then puts the result into D0. */°dONLNdm*
  7499. {°dONLNdp<&    +$
  7500. )return(SampleTransQueue(selector, q, p));°dONLNdö%0(L6}°dONLNdú9Dº*Tpascal long CallNetValidProc(ProcPtr p, TNetworkTransitionPtr netTrans, long theNet)°dONLNdÒCN®*
  7501. P/* CallNetValidProc is used to call the netValidProc pointed to by ProcPtr p. */°dONLNdBMX*
  7502. {°dONLNdEW<b¥+$
  7503. NetworkTransitionProcPtr°dONLNd^WÃb)ê myNTProcPtr;°dONLNdlk<v(íZ*myNTProcPtr = (NetworkTransitionProcPtr)p;°dONLNdòu<Ä*
  7504. *return ((*myNTProcPtr)(netTrans, theNet));°dONLNd√ä(¶6} ¡4¡˘
  7505. *038)
  7506.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ^◊#ˇ ˇˇˇˇ#◊ 
  7507. IR,Times
  7508. .+Z-Developer Support Center(-Á January 1993 /X/
  7509. °dONLNd)<8(TZMultivendor ADEV Architecture
  7510. °dONLNdD<PC*0With the release of AppleTalk version 56, Apple °dONLNdNDCP˛(la implemented the Multivendor ADEV°dONLNdoP<\Œ(xZRArchitecture. Under the original architecture with versions of AppleTalk prior to °dONLNd¡PŒ\˛(xÏ    56, using°dONLNdÀ\<h≠(ÑZIEtherTalk or TokenTalk on Macintosh II class machines permitted only one °dONLNd\≠h˛(ÑÀbrand of NuBus°dONLNd#h<tS(êZcard °dONLNd(hSt˛)Vwhere multiple Ethernet or token ring connections were desired. Furthermore, there was°dONLNdt<Ä(úZ*no support for a configuration of a NuBus °dONLNd©tIJ)À3slot device and a “slotless” device, such as a SCSI°dONLNd›Ä<åù(®ZEthernet connection.°dONLNdÚò<§ù*As Ethernet comes °dONLNdòù§˛)aEbuilt in on next-generation CPUs, this clearly presents a problem for°dONLNdJ§<∞Ì(ÃZ"customers wishing to mix Ethernet °dONLNdl§Ì∞˛)±2controller brands on the same CPU. The Multivendor°dONLNdü∞<º∂(ÿZArchitecture presents a °dONLNd∑∞∂º˛)z;common interface through which basic AppleTalk services are°dONLNdÛº<»´(‰Zprovided. The new °dONLNdº´»˛)o>architecture simplifies software development whereas AppleTalk°dONLNdD»<‘Q(Z6engineering provides the ADEV file, and the developer °dONLNdz»Q‘˛(o"provides the hardware level driver°dONLNdù‘<‡J(¸Z7software for Ethernet and token ring. By following the °dONLNd‘‘J‡˛(¸h$new architecture, Ethernet and token°dONLNd˘‡<Ï¥(ZGring hardware cards will be compatible as new services are provided by °dONLNd@‡¥Ï˛(“AppleTalk (for°dONLNdOÏ<¯/(Z-example, AppleTalk Remote Access and MacTCP).°dONLNd~<r*
  7511. AppleTalk °dONLNdàrπ)6?version 56 and later is compatible with system software version°dONLNd«π¿(,◊ °dONLNd»¿˛) 6.0.5 unless°dONLNd’< (8Z3specifically stated otherwise in the release notes.
  7512. °dONLNd
  7513. (<7≈*Original Limitations
  7514. °dONLNdC<Ofl*"The original product allowed only °dONLNdACflO˛)£:one type of NuBus Ethernet or token ring controller or one°dONLNd|O<[ª(wZ“slotless” controller. This °dONLNdòOª[˛)@Multivendor ADEV Architecture deals only with the restriction of°dONLNdŸ[<g0(ÉZ1differing NuBus controllers. It does not address °dONLNd
  7515. [0g˛)Ù)the mutual exclusion of slot and slotless°dONLNd4g<sb(èZAdevices, nor does it address the singularity of slotless devices.°dONLNdv<ãÂ*"NuBus slot Ethernet or token ring °dONLNdòÂã˛)©9controller hardware is recognized by the original product°dONLNd“å<òó(¥Zthrough a series of °dONLNdÊåóò€)[
  7516. Slot Manager ,
  7517. Courier°dONLNdÛã€óE)DSNextTypesRsrc °dONLNdåEò˛)j&calls. Any NuBus device that is in the°dONLNd)ò<§c(¿Znetwork°dONLNd0òc§,)'+ category and has a type classification of °dONLNd[ò,§S)…Ethernet°dONLNdcòS§W)' °dONLNddòW§ã) /token ring°dONLNdoòã§“)4 is considered °dONLNd~ò“§˛)Ga NuBus°dONLNdܧ<∞˘(ÃZ(slot controller device. Whenever such a °dONLNdƧ˘∞˛)Ω7device is found in a NuBus slot, the user can select it°dONLNdÊ∞<º‹(ÿZ!as the current AppleTalk network °dONLNd∞‹º˛)†=connection, or it can be used as a port in an Internet Router°dONLNdEº<»(‰Zconfiguration.°dONLNdT‘<‡Â*UWhen the AppleTalk network system uses this connection, an _Open, IMMED trap call is °dONLNd©‘‡˛(¸made°dONLNdƇ<Ïb(Zwith an °dONLNd∂‡bÏï)&    ioNamePtr°dONLNdø‡ïÏ&)3 -> “.ENET/.TOKN”, and the °dONLNd⁄‡&ÏB)ëioSlot°dONLNd‡‡BÏä) field set to the °dONLNdÚ‡äÏ˛)Hslot containing the card.°dONLNd     Ï<¯(Z&Since only one driver resource can be °dONLNd    2Ï¯˛)¥8installed in the system with this name, only one type of°dONLNd    k¯<ï( ZJEthernet or token ring card was supported under the original architecture.°dONLNd    ∂<ß*ENET Driver Shell°dONLNd    »(<4e*System °dONLNd    œ(e4˛))Lsoftware version 7.0 and later (and Network Software Installers (NSI) system°dONLNd
  7518. 4<@E(\Z5software version 1.1 and later) is packaged with the °dONLNd
  7519. Q4E@˛(\c$.ENET driver shell that will support°dONLNd
  7520. v@<L∑(hZSmultiple NuBus Ethernet controllers. The sole function of this driver is to locate °dONLNd
  7521. …@∑L˛(h’the appropriate°dONLNd
  7522. ŸL<Xç(tZIdriver resource for the particular device selected, and transfer control °dONLNd "LçX˛(t´to the open routine for°dONLNd :X<dG(ÄZ;that driver. It accomplishes this in the following fashion:°dONLNd vpN|ç+• Obtains the °dONLNd Ñpç|π)?Board ID°dONLNd åpπ|«),9 from the board sResource information for the given slot. ¡X¡
  7523. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙39)
  7524.  of 61(ÏZM.NW.AppleTalk2ˇ~◊#ˇ ˇˇˇˇ#◊ 
  7525. IR,Times
  7526. .+6-Macintosh Technical Notes /4/˘
  7527. °dONLNd*)1+• °dONLNd1)»)WFor the driver shell installed using NSI version 1.2.4 or later, the shell searches for°dONLNdZ)75©+ resources of type 'enet' °dONLNds)©5 )rwith the ID equal to the °dONLNdå) 5M)wBoard ID°dONLNdî)M5»)- in the System file and in°dONLNdØ57As(]U>the System ROM, and for a driver in the slot resources in the °dONLNdÌ5sA»(]ëROM of the slot°dONLNd˝A7M (iUdevice. It uses the word (2 °dONLNdA M»)ì-bytes) immediately following the DRVR name to°dONLNdGM7Y\(uU=determine which driver is the most recent; higher values are °dONLNdÑM\Y»(uznewer versions. If no°dONLNdöY7e¸(ÅU+driver is found, an open error is returned.°dONLNd«q7}P*For °dONLNdÀqP}»)Ethe driver shell installed prior to NSI version 1.2.4, the shell uses,
  7528. Courier°dONLNd}7âí(¶U
  7529. _GetResource °dONLNd~íä)[to obtain a resource of type °dONLNd;~ä´)É 'enet' with the ID equal to the °dONLNd[~´ä»)ñBoard°dONLNdaä7ñC(≤UID°dONLNdcäCñ) C from the system file. If the resource is present, proceeds to use °dONLNd¶äñ»(≤ùit as the driver°dONLNd∑ñ7¢P(æUcode °dONLNdºñP¢»)Nresource as defined below, otherwise attempts to load the driver from the slot°dONLNd ¢7Æò( ULresources in the ROM of the slot device. If neither code resource is found, °dONLNdW¢òÆ»( ∂
  7530. returns an°dONLNdbÆ7∫l(÷U open error.°dONLNdnΔ*“›(ÓH%• Detaches the newly loaded resource.°dONLNdîfl*Î*4• Modifies the device control entry for the current °dONLNd»fiÍ[)Î
  7531. _Open call°dONLNd“fl[Îv)F with °dONLNdÿflvλ)information from°dONLNdÈÎ7˜(U/the loaded driver code (address to the driver).°dONLNd*ì(+HM• Obtains the address of the open routine from the driver header information.°dONLNdg*'*0• JSRs to the open routine of the loaded driver.°dONLNdò3*?“*&• If the open is successful, returns, °dONLNdæ3“?»)®3otherwise recovers the handle for the loaded driver°dONLNdÚ?7Ké(gUand disposes of it.°dONLNdWcÚ(6-This very simple technique allows developers °dONLNd3WÚc⁄)⁄/to quickly repackage driver resources by simply°dONLNdccoΩ(ã6"changing the resource type and ID.°dONLNdÜ{á†*OBuilt-in Ethernet on newer CPUs makes use of the board sResource list for slot °dONLNd’{†á⁄(£æ zero, which°dONLNd·áì;(Ø6should °dONLNdËá;ì⁄)#Tbe present on all CPUs. These systems also have the Ethernet device sResource lists,°dONLNd=ìü+(ª69and also have the .ENET driver in the sResources as well.°dONLNdw´∑]*DThe Easy Install process supplied on the Network Software Installer °dONLNdª´]∑⁄(”{version 1.1 and later, and°dONLNd÷∑√c(fl6Hon the system software installers for 7.0 and later, install the driver °dONLNd∑c√⁄(flÅshell when it recognizes°dONLNd7√œ¬(Î6Qthat an Apple EtherTalk NB or Ethernet NB (or other Ethernet board with Board ID °dONLNdà√¬œ⁄(·8) is°dONLNd需Ñ(˜6installed in the system.
  7532. °dONLNd®Û†*'.TOKN Driver Shell
  7533. °dONLNdª**9The .TOKN driver shell is currently available from Apple °dONLNdÙ*⁄(6HSoftware Licensing (SW.LICENSE)°dONLNd&y(B6Cfor licensing. The driver and Multivendor TokenTalk ADEV are being °dONLNdWy&⁄(Bópackaged beginning°dONLNdj&2 (N61with system software version 7.0.1 and AppleTalk °dONLNdõ& 2⁄)Û*products that require AppleTalk version 57°dONLNdΔ2>
  7534. (Z65or later. The operation of the .TOKN driver shell is °dONLNd˚2
  7535. >⁄)ı+similar to the .ENET driver shell. In place°dONLNd    '>J\(f6Dof searching for and loading the 'enet' resource, a 'tokn' resource °dONLNd    k>\J⁄(fzwill be used instead. The°dONLNd    ÖJVΔ(r6[new driver will affect all developers whose .TOKN drivers get replaced by the driver shell.°dONLNd    ·bnì*.TOKN Driver Basics°dONLNd    ızÜJ*;The following guidelines describe the minimum requirements °dONLNd
  7536. 0zJÜ⁄(¢hfor developers of token ring°dONLNd
  7537. MÜí](Æ6?products for the Macintosh to be compatible with the TokenTalk °dONLNd
  7538. åÜ]í⁄(Æ{Phase 2 driver software. ¡4¡˘
  7539. (÷640)
  7540.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ:◊#ˇ ˇˇˇˇ#◊ 
  7541. IR,Times
  7542. .+Z-Developer Support Center(-Á January 1993 /X/
  7543. °dONLNd<)i(EZMacDTS °dONLNdi)˛)-Rstrongly recommends that all developers of token ring products implement the basic°dONLNdZ)<5{(QZBfunctionality described below. By following these guidelines, the °dONLNdú){5˛(Qôproduct will be compatible°dONLNd∑5<A(]Z&with AppleTalk Remote Access, MacTCP, °dONLNd›5A˛)€,and future releases of AppleTalk and related°dONLNd
  7544. A<Mi(iZ    products.°dONLNdY<e*0The .TOKN driver is similar to the structure of °dONLNdDYe˛)‡,the .ENET driver as described in Appendix B,°dONLNdqe<q√(çZ“Macintosh Ethernet Driver °dONLNdåe√q)áDetails” in the °dONLNdúeq˛)K,Macintosh AppleTalk Connections Programmer’s°dONLNd…q<}Y(ôZGuide°dONLNdŒqY}9)- (Final Draft 2, November 11, 1989) and more °dONLNd˚q9}o)‡ recently in °dONLNdqo}¡)6Inside Macintosh°dONLNdq¡}˛)R  Volume VI,°dONLNd#}<â—(•Zpage 32-88. These documents °dONLNd?}—â˛)ï<describe the expected functionality of the .ENET driver. The°dONLNd|â<ïd(±Z.TOKN °dONLNdÇâdï˛)(Wdriver interface that you design can be a superset of the functionality discussed here.°dONLNd⁄ï<°ì(ΩZHThe following are some additional guidelines and exceptions to consider:°dONLNd#ÆN∫R+•°dONLNd%Æ[∫n)
  7545. 9The driver can obtain the slot number from the DCE entry ,
  7546. Courier°dONLNd^≠nπ¶(÷ådCtlSlot°dONLNdfƶ∫™)8.°dONLNdh«N”R(Ôl•°dONLNdj«[”Ï)
  7547. The driver need only support °dONLNdáΔÏ“)ëEAttach°dONLNdé«”r)1 protocol type 0. °dONLNd†«r”Ï)UReturn an error on other°dONLNdπ”[fl¢(˚yprotocol types.°dONLNd…ÏN¯R(l•°dONLNdÀÏ[¯Õ)
  7548. Implement the add and °dONLNd·ÏÕ¯ó)r*delete functional address in place of the °dONLNd Îó˜÷)     EAddMulti°dONLNdÏ÷¯Ï)? and°dONLNd¯[°(!y
  7549. EDelMulti °dONLNd#˘°ÿ)F    commands.°dONLNd-NR(:l•°dONLNd/[û)
  7550.  
  7551. Implement the°dONLNd<ûÚ)C  ESetGeneral°dONLNdHÚÑ)T" call to return a result of noErr.°dONLNdk*N6R(Rl•°dONLNdm*[6›)
  7552. Implement source routing °dONLNdÜ*›6Ï)Ç6support if the driver is to support the source routing°dONLNdΩ6[BÇ(^ybridges.°dONLNdΔO<[T(wZ• On °dONLNdÀNTZ~)EWrite°dONLNd—O~[î)* call:°dONLNdŸg`s“(è~The first buffer in the °dONLNdÒg“sÏ)r3WDS contains a 802.3 MAC header (6-byte destination°dONLNd%sN¬(õladdress + 6-byte source °dONLNd=s¬Ï)t>address + 2-byte length field). The 6-byte destination address°dONLNd|Nã≠(ßlMis the only important field to the driver. The source address and the length °dONLNd…≠ãÏ(ßÀfields are not°dONLNdÿãNóh(≥l<used for token ring media. The header is 14 bytes in length.°dONLNd£`Ø∞+BThe second buffer in the WDS contains the LLC header and the SNAP °dONLNdX£∞ØÏ(ÀŒ header. This°dONLNdeØNªÀ(◊lbuffer is 8 bytes in length.°dONLNdÉ«`”,+*The remainder of the WDS is the user data.°dONLNdØfl`Δ*NThe packet that gets put out on the “wire” will not include the 2-byte length °dONLNd˝fl”ÎÏ(Òfield.°dONLNdÎN˜®(lEThe packet header will have the 6-byte destination address, followed °dONLNdIή˜Ï(Δ
  7553. by the 6-byte°dONLNdW˜N∞(lGsource address, followed by the LLC and SNAP header, and the user data.°dONLNd†<|(7Z
  7554. • On Receive:°dONLNdØ'`3
  7555. +$ Define a Read Header Area (RHA) °dONLNdœ'
  7556. 3Ï)≠*into which to create the 14 byte 802.3 MAC°dONLNd˙3N?`([l9header. Read the header into the RHA and set A3 to point °dONLNd33`?Ï([~to the end of the RHA; place°dONLNdP?NKù(glGthe 6-byte destination and source addresses into the first 12 bytes of °dONLNdó?ùKÏ(gª
  7557. the RHA. From°dONLNd•KNWB(sl5the hardware, get the length of the packet and place °dONLNd⁄KBWÏ)Ù$it into the last 2 bytes of the RHA.°dONLNdˇWNc (lThis step is necessary as °dONLNd    W cÏ)|8the LAP Manager is designed to handle and Ethernet style°dONLNd    RcNop(ãlpacket.°dONLNd    [{`á¬+ICalculate the packet length (LLC header + SNAP header + data). Place the °dONLNd    §{¬áÏ(£‡    length in°dONLNd    ÆáNì›(Ølregister D1.W. Also place the °dONLNd    Ãá›ìÏ)è6computed length into the length field of the 802.3 MAC ¡X¡
  7558. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙41)
  7559.  of 61(ÏZM.NW.AppleTalk2ˇ`◊#ˇ ˇˇˇˇ#◊ 
  7560. IR,Times
  7561. .+6-Macintosh Technical Notes /4/˘
  7562. °dONLNd*)∫+Qheader (this length does not include the source routing and 802.5 fields). Place °dONLNdQ∫)»(Eÿthe°dONLNdU**6r(RHaddress of the ,
  7563. Courier°dONLNdd)r5∏)H
  7564. ReadPacket°dONLNdn*∏6˜)F routine into °dONLNd|*˜6»)?,register A4. Disable the interrupt. Call the°dONLNd©7*Cö(_Hprotocol handler or use °dONLNd¡6öBÁ)p DeferUserFn°dONLNdÃ7ÁC´)M* as described below. Enable the interrupt.°dONLNd¯O<[G(wZ:As A0 is reserved for use by the driver, it could be used °dONLNd2OG[»(weto point to the next byte to°dONLNdO[*gb(ÉHAbe read by the driver, for the ReadPacket and ReadRest functions.°dONLNdës[(õ6• Other Notes:°dONLNd†ã*óF+If the °dONLNdßãFó»)Pprotocol handler calls your ReadRest routine with a buffer too small to hold the°dONLNd¯ó*£(øH2entire remaining packet, set the Z-bit in the CCR °dONLNd*ó£»)$before returning. Clearing the Z-bit°dONLNdO£*Øg(ÀHDindicates that the ReadRest routine handled the packet successfully.
  7565. °dONLNdî«÷7(Ú6(Driver Considerations for Virtual Memory
  7566. °dONLNdΩ‚ÓB*@With the release of system software version 7.0 and the virtual °dONLNd˝‚BÓ⁄(
  7567. `!memory option, it is critical for°dONLNdÓ˙7(6driver °dONLNd&Ó7˙⁄)Ysoftware to protect against the possibility of a double page fault. Since driver software°dONLNdÄ˙’("6^runs at interrupt time, a non-virtual memory compatible packet processing routine could cause °dONLNdfi˙’⁄("Ûa°dONLNd‡¬(.6"page fault while the Macintosh is °dONLNd¬⁄)™8already processing a page fault. To protect against this°dONLNd;c(;6possibility, the °dONLNdLc∞)K DeferUserFn,    Geneva°dONLNdW∞ µ)M °dONLNdXµï)0is provided to allow interrupt service routines °dONLNdàï⁄)‡to defer code,°dONLNdó+è(G6Qwhich might cause a page fault, until a safe time. The following guidelines will °dONLNdËè+⁄(G≠help make your°dONLNd˜+7Í(S6+driver code compatible with virtual memory.°dONLNd#C*O˚++• In the Open routine, use Gestalt to test °dONLNdNC˚O»)—'for the presence of virtual memory, and°dONLNdvP7\Ù(xU+whether it’s on. If so, set a flag in your °dONLNd°OÙ[A)Ω dctlstorage°dONLNd¨PA\Δ)M that you can reference later.°dONLNdÀi*uÙ(ëH+• If virtual memory is enabled, always use °dONLNdˆhÙtA)  DeferUserFn°dONLNdiAu≤)M to defer the delivery of °dONLNdi≤u»)qyour°dONLNd u7ņ(ùUQpacket data to your clients. This is necessary to protect against page faults at °dONLNdqu†Å»(ùæ    interrupt°dONLNd{Å7ç    (©U*time when your client reads data into her °dONLNd•Å    ç»)“"own (probably unlocked) memory. In°dONLNd»ç7ô°(µUJaddition, do not touch any memory that is not locked down (in the virtual °dONLNdç°ô»(µømemory°dONLNdô7•ê(¡UFsense, not the Memory Manager sense) while processing your interrupts.°dONLNd`≤*æT(⁄H
  7568. • Set the °dONLNdj±TΩ°)* VMImmuneBit°dONLNdu≤°æ≠)M7 to keep the system from locking down memory (bit 0 at °dONLNd¨≤≠æ»(⁄Àoffset°dONLNd≥æ7 o(ÁUdCtlFlag
  7569. °dONLNdªøoÀs)8s
  7570. °dONLNdºøsÀ§)
  7571.  + 1). If °dONLNdΔø§À∏)1the °dONLNd æ∏ ) VMImmuneBit°dONLNd’øÀ»)M' isn’t set, the system locks the user’s°dONLNd˝À7◊˘(ÛU)parameter block. In contrast, the user’s °dONLNd&À˘◊»)¬(buffers remain unlocked unless locked by°dONLNdO◊7„Ç(ˇUthe application. °dONLNd`◊Ç„»)KEAs a result, it is necessary to assume that the buffers are unlocked,°dONLNd¶‰7j( U and to use °dONLNd±„jÔ∑)3 DeferUserFn°dONLNdº‰∑j)M% accordingly. Having the system lock °dONLNd·‰j»)≥the parameter block°dONLNdı7¸Z(Uresults °dONLNd˝Z¸»)#Kin a noticeable performance hit. The solution to this problem is to set the°dONLNd    I¸7Ñ(%U VMImmuneBit°dONLNd    T˝Ñ    Ó)M, and to be careful to °dONLNd    k˝Ó    »)j+“touch” the parameter block only when it is°dONLNd    ó    7£(1UG“safe” to do so. One time when it might be “unsafe” is in a completion °dONLNd    fi    £»(1¡routine.°dONLNd    Á7"(>UTherefore, use °dONLNd    ˆ!Ã)H DeferUserFn°dONLNd
  7572. Ã"”)M .°dONLNd
  7573. /;/(W6The °dONLNd
  7574. ./:g)VMImmune°dONLNd
  7575. /g;⁄)8F bit is not currently found in the MPW headers. Add the following line°dONLNd
  7576. W;G˝(c6/somewhere at the beginning of your driver code:
  7577. °dONLNd
  7578. âS_Ã*      VMImmuneBit     EQU    0
  7579. °dONLNd
  7580. ™jvD*;Somewhere in the beginning of your code, assuming that the °dONLNd
  7581. ÂjDv÷(íbdriver is now virtual memory°dONLNd j÷v⁄)í-°dONLNd vÇ•(û6aware, add the following line: ¡4¡˘
  7582. *842)
  7583.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇÓ◊#ˇ ˇˇˇˇ#◊ 
  7584. IR,Times
  7585. .+Z-Developer Support Center(-Á January 1993 /X/,
  7586. Courier°dONLNd<),(EZ(      BSET  #VMImmuneBit,dCtlFlags+1(A1)°dONLNd)8)Ü)¸
  7587. ; set the bit
  7588. °dONLNd95<Ap(]ZWarning:°dONLNdA5pAs)4 °dONLNdC5ÑAó)Do °dONLNdF5óAÏ)not assume that °dONLNdV4Ï@9)U DeferUserFn°dONLNda59A⁄)M will always successfully queue°dONLNdÅAÑM∂(i¢=your packet-handling routine. Check the return result. Under °dONLNdæA∂M⁄(i‘specific°dONLNd«MÑY©(u¢9situations, the Defer-Function Queue can become full. If °dONLNdM©Y⁄(u«
  7589. the return°dONLNd ZÑf¨(Ç¢
  7590. result is °dONLNdY¨e)(cannotDeferErr°dONLNd#Zf)b °dONLNd$Zf⁄)-exit the slot interrupt routine with a result°dONLNdRfÑrì(é¢=of zero to indicate that the interrupt could not be serviced.°dONLNdí~<ä⁄(¶ZLimiting DeferUserFn Calls°dONLNd≠ó<£*.Your interrupt service routine can reduce the °dONLNd€ó£l)‘number of calls to °dONLNdÓñl¢π)\ DeferUserFn°dONLNd˘óπ£˛)M
  7591.  depending on°dONLNd£<ØÂ(ÀZ!the Network Interface Controller °dONLNd(£ÂØ˛)©0(NIC) being used. With the SONIC and other NICs,°dONLNdYØ<ª(◊Z-incoming packets are queued. An ISR for such °dONLNdÜØª˛)‡-a NIC can be designed to process not only the°dONLNd¥ª<«˘(„Z)packet that generated the interrupt, but °dONLNd›ª˘«˛)Ω4also successive packets. As a result, the ISR can be°dONLNd«<”Ö(ÔZdesigned to set °dONLNd"«Ö”˛)IPa “deferred function” flag to indicate that the service routine has been queued,°dONLNds”<flâ(˚ZAthen process all packets that it finds in the card’s queue. When °dONLNd¥”âfl˛(˚ßthe service routine has°dONLNdÃfl<΃(Zcompleted, it can then reset °dONLNdÈflƒÎ˛)àAthe deferred function flag. If the ISR is reentered, it can check°dONLNd+Î<˜R(Z>whether the deferred function flag is set. If so, simply exit °dONLNdiÎR˜˛(p$with a nonzero result in register D0°dONLNdé˜<˛(Z*to indicate that the packet was processed.°dONLNd∫<p* Using this °dONLNd≈p˛)4Valgorithm, it is important to reset the NIC’s interrupt service register each time the°dONLNd<'…(CZUISR determines that a packet will be processed by a previously deferred function. If °dONLNdq…'˛(CÁ the register°dONLNd~'<3Ï(OZais not cleared, the card will remain in a constant state of interrupt, and the deferred function °dONLNdfl'Ï3˛(O
  7592. will°dONLNd‰3<?»([Znever get a chance to execute.°dONLNdK<W÷*Implementing DeferUserFn°dONLNdd<p≈*The question may arise as to °dONLNd9d≈p:)âwhere to implement the °dONLNdPc:oá)u DeferUserFn°dONLNd[dáp˛)M The following approach°dONLNdsp<|ª(òZis one possible suggestion °dONLNdépª|˛)Bfor devices that are not able to empty the NIC’s packet RAM all at°dONLNd—|<à…(§Zonce, and which implement a °dONLNdÌ|…à˛)çBcircular buffer or linked buffer list. Define an entry point where°dONLNd0à<î<(∞Z4the ISR begins processing the packet from the card. °dONLNddà<î˛(∞Z&At this entry point, there may be some°dONLNdãî<†Í(ºZYcode to check whether a packet transmission is under way and to perform a cleanup. There °dONLNd‰î͆˛(ºmay°dONLNdˆ<¨Ò(»Z#also be code here to check whether °dONLNd †Ò¨˛)µ2the buffer has become overrun and to reset the NIC°dONLNd>¨<∏√(‘Zaccording to manufacturer’s °dONLNdZ¨√∏˛)á>guidelines. The driver code would copy the header into the RHA°dONLNdô∏<ƒ°(‡Z(Read Header Area), °dONLNd≠∏°ƒ˛)eJidentify the protocol handler and set up register A4 with a pointer to the°dONLNd¯ƒ<–∑(ÏZJReadPacket routine, then call the handler. Upon completion, the ISR might °dONLNd    Bƒ∑–˛(Ï’
  7593. check whether°dONLNd    P–<‹≤(¯Zadditional packets have °dONLNd    h–≤‹˛)vBbeen received, if applicable. A flowchart of the deferred function°dONLNd    ´‹<Ë¢(Zprocess is as follows:
  7594.     °dONLNd    ¬Ù<ˇõ*myDeferedFunction()°dONLNd    ÷˛<    A*
  7595. {°dONLNd    ÿ<¥*
  7596.     If transmit complete°dONLNd    Ò<'*
  7597. /        do final cleanup of packet transmission°dONLNd
  7598. #&<1•*    If buffer overrun°dONLNd
  7599. 90<;h*
  7600. <        Reset the NIC according to manufacturer's guidelines°dONLNd
  7601. xD<OJ*6    while(received packets are waiting in adapter ram)°dONLNd
  7602. ØN<YU*
  7603.     {°dONLNd
  7604. µX<c™*
  7605.         process packet°dONLNd
  7606. Ãb<mÕ*
  7607.         call protocol handler°dONLNd
  7608. Íl<wU*
  7609.     }°dONLNd
  7610. v<ÅA*
  7611. } ¡X¡
  7612. *9(NW 13 - AppleTalk: The Rest of the Story(÷˙43)
  7613.  of 61(ÏZM.NW.AppleTalk2ˇ,◊#ˇ ˇˇˇˇ#◊ 
  7614. IR,Times
  7615. .+6-Macintosh Technical Notes /4/˘
  7616. °dONLNd)**:On entry to the ISR, see whether virtual memory is active °dONLNd:*)⁄(EH$by checking the flag set by the open°dONLNd_)5l(Q6routine. Perform °dONLNdp)l5⁄)THwhatever processing is necessary, then pass DeferUserFn, the entry point°dONLNdπ5AÀ(]6&described above, if virtual memory is °dONLNdfl5ÀA⁄)≥:active. If virtual memory is inactive, branch to the entry°dONLNdAM°(i6point and process the packet.
  7617. °dONLNd8etò*'5SONIC-Based Ethernet Driver Software Interface Change
  7618. °dONLNdnÄå<*;With the introduction of SONIC-based Ethernet controllers, °dONLNd©Ä<å⁄(®Za modification was implemented°dONLNd»åò@(¥6    into the °dONLNd—å@ò⁄)(REthernet driver software to return additional information available from the SONIC°dONLNd$ò§Y(¿6
  7619. chip network °dONLNd1òY§⁄)ARstatistics counters. This section describes the format of the information returned°dONLNdÑ•±5(Õ6by an ,
  7620. Courier°dONLNdä§5∞m)EGetInfo°dONLNdí•m±p)8 °dONLNdì•p±⁄)Hcall when the current network connection is through an Ethernet NB Card,°dONLNd‹±Ωà(Ÿ6an Ethernet LC Card, °dONLNdÒ±àΩ⁄)pBor through the built-in Ethernet available on the Macintosh Quadra°dONLNd4Ω…X(Â6 700/900/950.°dONLNdA’·Ä*EGetInfo Changes°dONLNdRÓ˙/*The °dONLNdVÌ/˘p)    EGetInfo °dONLNd_Óp˙<)A*call can return up to 60 additional bytes °dONLNdâÓ<˙⁄)Ãof new information making the°dONLNdß˙J("6maximum °dONLNdØ˙J⁄)2Lnumber of bytes returned 78. As with the Apple EtherTalk NB Card (Apple/3Com°dONLNd¸…(.6[card), the first 6 bytes returned contain the card’s Ethernet address. The remaining bytes °dONLNdW…⁄(.Áthat°dONLNd\_(:6Care returned contain information different from that returned with °dONLNdü_⁄(:}the Apple EtherTalk NB°dONLNd∂*3(F6Card.°dONLNdº6B∞* The next 12 bytes (offset 6–17) °dONLNd‹6∞B⁄)ò<returned contain NO information but are always returned zero°dONLNdBNfi(j6+filled for compatibility. The remaining 60 °dONLNdDBfiN⁄)Δ3bytes returned contain SONIC chip network statistic°dONLNdxNZã(v6Pcounters. The counters are listed below in the following table with the decimal °dONLNd»NãZ⁄(v©and hexadecimal°dONLNdÿZfø(Ç6$offsets given from the start of the °dONLNd¸Zøf⁄)ß<return buffer. Note that the offset of the first item in the°dONLNd9frˇ(é64return buffer, the Ethernet address, is at offset 0.
  7621. °dONLNdn~ä*(Byte offset:(start at 0)     Description°dONLNdóî†&*-18    ($12)       -     Frames transmitted OK°dONLNd≈ü´2* /22    ($16)       -     Single collision frames°dONLNdı™∂™* C                  26    ($1A)       -     Multiple collision frames°dONLNd9µ¡t* :                  30    ($1E)       -     Collision frames°dONLNdt¿Ã⁄* K                  34    ($22)       -     Frames with deferred transmission°dONLNd¿À◊h* 8                  38    ($26)       -     Late collision°dONLNd˘÷‚å* >                  42    ($2A)       -     Excessive collisions°dONLNd8·ÌÜ* =                  46    ($2E)       -     Excessive deferrals°dONLNdvϯ∂* E                  50    ($32)       -     Internal MAC transmit error°dONLNdº˜Ä* <                  54    ($36)       -     Frames received OK°dONLNd˘º* F                  58    ($3A)       -     Multicast frames received OK°dONLNd    @
  7622. º* F                  62    ($3E)       -     Broadcast frames received OK°dONLNd    á$∂* E                  66    ($42)       -     Frame check sequence errors°dONLNd    Õ#/t* :                  70    ($46)       -     Alignment errors°dONLNd
  7623. .:Œ* I                  74    ($4A)       -     Frames lost due to internal MAC°dONLNd
  7624. S9Eí* ?                                                  receive error
  7625. °dONLNd
  7626. ì\h“*#ZWith the release of AppleTalk version 58, a minor change was implemented into the EGetInfo°dONLNd
  7627. Óht‘* dcall such that the number of bytes filled in by the call, is returned in the eDataSize field. The re°dONLNd Rh‘tÿ(êÚ-°dONLNd StÄ÷(ú6]vised parameter block description for the .ENET driver supplied with AppleTalk version 58 is: ¡4¡˘
  7628. *:44)
  7629.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  7630. IR,Times
  7631. .+Z-Developer Support Center(-Á January 1993 /X/†Ç†å°ñ °öˇ¸Ì
  7632. >[J,
  7633. Courier
  7634. .à¬àfl°dONLNdˇˇ(H\DFUNCTION EGetInfo (thePBPtr: EParamBlkPtr; async: Boolean) :  OSErr;†ó°ñ °ö'‰
  7635. blƒ, Palatinoà°dONLNdˇˇ+$Parameter Block
  7636. \Á°dONLNdˇˇ*T                    16          ioResult                    word        result code
  7637. 㥰dONLNdˇˇ*d                    24          ioRefNum                word        driver reference number        
  7638. f°dONLNdˇˇ*[                    26          csCode                      word        always ENetGetInfo
  7639. ¸∑°dONLNdˇˇ*[                    30          ePointer                    long         pointer to buffer
  7640. ∂ó°dONLNdˇˇ*V                    34          eBuffSize                  word        size of buffer
  7641. ì5°dONLNdˇˇ*^                    36          eDataSize                 word        number of bytes returned†ó°d
  7642. MDPL    †å
  7643. =Z≈qq}yäu}qäuäyäu}"uä †ç°dMDPL
  7644. °d
  7645. MDPL    †åqπ}¡äΩ}πäΩä¡äΩ}"Ωä †ç°dMDPL
  7646. °d
  7647. MDPL    †åqÄâàñÑñàâÑâÄâÑñ"ÑâÙ†ç°dMDPL
  7648. °d
  7649. MDPL    †åqéâññíññâíâéâíñ"íâÙ†ç°dMDPL
  7650. °d
  7651. MDPL    †åqúà§ñ†ñ§à†àúà†ñ"†àı†ç°dMDPL
  7652. °d
  7653. MDPL    †åq™à≤ñÆñ≤àÆà™àÆñ"Æàı†ç°dMDPL
  7654. †ç†É
  7655. IR"<W# <X<"<#"≈W# ≈X≈"≈# =WƒW =ƒ.°dONLNdø<Ày(ÁZ3Distinguishing Apple’s SONIC-Based Ethernet Systems°dONLNd4ÿ<‰ï*When making the °dONLNdD◊ï„Õ)YEGetInfo°dONLNdLÿÕ‰›)8< call, it is important to pass the correct size buffer. The °dONLNdàÿ›‰˛(˚control°dONLNdêÂ<Ò˚(
  7656. Z+call will only fill in the buffer with the °dONLNdªÂ˚Ò°)ø!number of bytes specified in the °dONLNd‹‰°‡)¶    eBuffSize°dONLNdÂÂ‡Ò˛)? field.°dONLNdÌÒ<˝◊(Z Unless it is already known that °dONLNd
  7657. Ò◊˝˛)õ9the active Ethernet card is the Apple (3Com) EtherTalk NB°dONLNdG˝<    (%Z(Card, it is recommended that you pass a °dONLNdo˝    ˛)»1buffer large enough to accommodate the additional°dONLNd°    <œ(1ZQinformation returned by the driver for the SONIC chip. One method to distinguish °dONLNdÚ    œ˛(1Ì    the Apple°dONLNd¸<!©(=Z(3Com) EtherTalk NB °dONLNd©!˛)mDCard from Apple’s SONIC-based systems, is to fill the 78-byte buffer°dONLNdU!<-¡(IZRwith a byte pattern like 0xFF. For the Apple EtherTalk NB Card, the last 60 bytes °dONLNdß!¡-˛(Ifl
  7658. of the buffer°dONLNdµ-<9◊(UZYwill still be filled with the byte pattern. For Apple’s SONIC-based systems, the last 60 °dONLNd-◊9˛(Uıbytes of°dONLNd9<EÇ(aZthe buffer will °dONLNd'9ÇEë)Fnot°dONLNd*9ëE) all contain the byte pattern.°dONLNdJQ<]à(yZ>With the Ethernet driver released under AppleTalk version 58, °dONLNdàQà]˛(y¶an alternate method to°dONLNdü]<i£(ÖZMdistinguishing the two Apple Ethernet hardware cards is to pass in a pointer °dONLNdÏ]£i˛(Ö¡to a 78-byte buffer°dONLNdi<uÉ(ëZin the ePointer °dONLNdiÉu˛)GPfield, then to check the EDataSize value for the number of bytes filled into the°dONLNdau<Å≈(ùZTbuffer. For the original EtherTalk NB card, the number of returned bytes is 18; for °dONLNdµu≈Ş(ù„ the Ethernet°dONLNd¬Å<ç)(©Z1NB card, the number of returned bytes will be 78.
  7659. °dONLNdÙ•<¥<*'$Correction to the ENET.h Header File
  7660. °dONLNd¿<Ã^*7Programs written for compilation with MPW C, which use °dONLNdP¿^Ã˛(Ë|the ENET.h header file supplied°dONLNdpÃ<ÿı(ÙZ&with MPW version 3.2.x are alerted to °dONLNdñÃıÿ˛)π9the fact the following declaration is incorrect. Users of°dONLNd–ÿ<‰⁄(ZWThink C should check their ENET.h header file for the same error, as the version 5.0.x °dONLNd'ÿ⁄‰˛(¯product°dONLNd/‰<•( ZIwas shipped with the header files supplied by the MPW team. This problem °dONLNdx‰•˛( √does not affect the°dONLNdå<¸‚(Z$corresponding Pascal interface file.
  7661. °dONLNd±<ú*typedef struct {°dONLNd¬<®*       EParamHeader°dONLNd’<*ÿ*       EParamMisc1 EParms1;°dONLNd)<5∂* ?      char eMultiAddr[5];                 /*Multicast Address*/°dONLNd04<@ä*
  7662. }EParamMisc2;
  7663. °dONLNd>K<W≈*The correct declaration has °dONLNdZK≈W˛)â;the eMultiAddr field immediately following the EParamHeader°dONLNdñW<cî(ZLstructure and the character array allocated 6 instead of 5 bytes as follows: ¡X¡
  7664. *W(NW 13 - AppleTalk: The Rest of the Story(÷˙45)
  7665.  of 61(ÏZM.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  7666. IR,Times
  7667. .+6-Macintosh Technical Notes /4/˘,
  7668. Courier°dONLNd)x*typedef struct {°dONLNd(4Ñ*       EParamHeader°dONLNd$3?í* ?      char eMultiAddr[6];                 /*Multicast Address*/°dONLNdd>Jf*
  7669. }EParamMisc2;
  7670. °dONLNdrUa§*NThe EParamMisc2 structure applies only to the EAddMulti and EDelMulti control °dONLNd¿U§a⁄(}¬ calls to the°dONLNdÕam∏(â6YEthernet, token ring and FDDI drivers. If you are using these calls, you might include a °dONLNd&a∏m⁄(â÷revised°dONLNd.my˙(ï62structure declaration in your source code file so °dONLNd`m˙y⁄)‚-that you need not worry about overwriting the°dONLNdéyÖ˘(°6/corrected header file when supplied with a new °dONLNdΩy˘Ö⁄)·+version of MPW. The declaration would be as°dONLNdÈÖë?(≠6follows:
  7671. °dONLNdÚù©~*#include <ENET.h>°dONLNd®¥* .°dONLNd≥ø* .°dONLNdæ Œ* I/* The following structure declaration replaces the incorrect EParamMisc2°dONLNdS…’»* H * structure declaration presented in the ENET.h files supplied with MPW°dONLNdù‘‡‰* " * to v3.2.4 and possibly greater.°dONLNd¿flÎ**  */°dONLNdƒÍˆx* typedef struct {°dONLNd’ıÑ*       EParamHeader°dONLNdË í* ?      char eMultiAddr[6];                 /*Multicast Address*/°dONLNd( ~* }EParamMultiCast;
  7672. °dONLNd:.=*&$AppleTalk Multiple Node Architecture
  7673. °dONLNd_IU_*ASupporting multiple node addresses on a single machine connected °dONLNd†I_U⁄(q}to AppleTalk is a feature°dONLNd∫Ua{(}6Ithat has been created to support software applications such as AppleTalk °dONLNdU{a⁄(}ôRemote Access. Its°dONLNdamv(â6Jimplementation is general enough to be used by other applications as well.°dONLNdayÖ7*Note:°dONLNdgy<Ö)$-AppleTalk version 57 or later is required to °dONLNdîyÖ∂)fisupport the AppleTalk Multiple°dONLNd≥Ö<ë[(≠ZNode °dONLNd∏Ö[ë∂)CArchitecture. Version 57 is compatible with system software version°dONLNd¸ë<ùé(πZD6.0.5 and later. If you implement multinode functionality into your °dONLNd@ëéù∂(π¨program°dONLNdHù<©q(≈Z:you should also plan to include AppleTalk version 57 with °dONLNdÇùq©∂(≈è
  7674. your product.°dONLNdê©<µ®(—ZEContact Apple’s Software Licensing department (see end of this Note) °dONLNd’©®µ∂(—Δfor°dONLNdŸµ<¡Á(›Z#information on licensing AppleTalk.°dONLNd˝ÕŸW(ı6 What Is It?°dONLNd    ÂÒ¶*PMultiple Node AppleTalk provides network node addresses that are in addition to °dONLNdY¶Ò⁄(
  7675. the normal°dONLNddÒ˝ƒ(6V(user node) DDP address assigned when AppleTalk is opened. These additional addresses °dONLNd∫Òƒ˝⁄(‚have°dONLNdø˝    ¬(%6%different characteristics from those °dONLNd‰˝¬    ⁄)™7of the user node address. They are not connected to the°dONLNd    (162protocol stack above the data link layer. When an °dONLNdN    ⁄(1<%application acquires a multinode, the°dONLNdt!…(=6\application has to supply a receive routine through which AppleTalk will deliver broadcasts °dONLNd–…!⁄(=Áand°dONLNd‘!-‡(I6+packets directed to that multinode address.°dONLNd9E:*;The number of multinode addresses that can be supported on °dONLNd;9:E⁄(aX one single machine is determined°dONLNd\EQJ(m6 by a static °dONLNdhEJQ⁄)2Qlimit imposed by the AppleTalk ADEV itself (for example, EtherTalk). The limit is°dONLNd∫Q];(y6<currently 253 nodes for Apple’s implementation of EtherTalk °dONLNdˆQ;]⁄(yY($0, $FF, and $FE being invalid°dONLNd    ]iÅ(Ö6node addresses) and °dONLNd    *]Åi⁄)i@254 for LocalTalk ($0 and $FF being invalid node addresses). The°dONLNd    kiuç(ë6Pnumber of receive routines that .MPP supports is determined by the static limit °dONLNd    ªiçu⁄(ë´of 256. If all of°dONLNd    ÕuÅe(ù6Gthe multiple nodes acquired need to have unique receive routines, then °dONLNd
  7676. ueÅ⁄(ùÉonly a maximum of 256°dONLNd
  7677. *ÅçL(©6=nodes can be acquired, even if the ADEV provides support for °dONLNd
  7678. gÅLç⁄(©jmore than 256 nodes. .MPP ¡4¡˘
  7679. (÷646)
  7680.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇé◊#ˇ ˇˇˇˇ#◊ 
  7681. IR,Times
  7682. .+Z-Developer Support Center(-Á January 1993 /X/
  7683. °dONLNd<)è(EZwill support the °dONLNdè)˛)SGlesser of either the maximum of 256 receive routines, or the node limit°dONLNdY)<5™(QZimposed by the ADEV.°dONLNdnA<M*)Outbound DDP packets can be created with °dONLNdóAMc)÷a user-specified °dONLNd®AcMÌ)Qsource network, node, °dONLNdæAÌM˛)äand°dONLNd¬M<Y`(uZsocket°dONLNd»M`Yô)$> (normally equal to a multinode address) with the new Network °dONLNdMôY˛(u∑Write call. With this°dONLNdY<e](ÅZ;capability and the packet reception rules described above, °dONLNdWY]e˛(Å{ a single machine can effectively°dONLNdxe<q(çZ'become several nodes on a network. The °dONLNdüeq)ƒuser°dONLNd£eqÈ)- node continues to function as it always has.°dONLNd—}<â(•Z%Glue Code for Multinode Control Calls°dONLNd˜ï<°Ê*!The following files are provided °dONLNdïʰ˛)™1for C and Pascal programmers to implement the new°dONLNdJ°<≠â(…ZFmultinode calls presented in this Tech Note. First, for C programmers:,
  7684. Courier
  7685.     °dONLNdëπ<ƒ§*H/*----------------------------------------------------------------------°dONLNd⁄√<Œõ*
  7686.   file: MultiNode.c°dONLNdÓÕ<ÿ§*
  7687. H----------------------------------------------------------------------*/°dONLNd7·<Ïñ*#include <Types.h>°dONLNdJÎ<ˆ†*
  7688. #include <Devices.h>°dONLNd_ı<†*
  7689. #include <OSUtils.h>°dONLNdtˇ<
  7690. ™*
  7691. #include <AppleTalk.h>°dONLNdã<Z*enum {°dONLNdí'<2Õ*/*  MultiNode .MPP csCodes */°dONLNd∞;<Fü*G    netWrite = 261,                 /* Send packet through multinode */°dONLNd¯E<Pm*
  7692. =    addNode = 262,                  /* Request a multinode */°dONLNd6O<Z^*
  7693. :    removeNode = 263,               /* Remove multinode */°dONLNdqY<dF*
  7694. };°dONLNdtm<xå*typedef struct {°dONLNdÖw<Çå*
  7695.     MPPATPHeader°dONLNdóÅ`å°+$
  7696.  
  7697. char filler1;°dONLNd¶ã`ñ™*
  7698. Bunsigned char checkSumFlag;     /* perform checksum on datagram */°dONLNdÍï`†•*
  7699. APtr wdsPointer;                 /* Ptr to write-data structure */°dONLNd-ü`™∞*
  7700. char filler2[2];°dONLNd?©`¥É*
  7701. union {°dONLNdH≥`æ•*
  7702. A    AddrBlock reqNodeAddr;      /* preferred address requested */°dONLNdãΩ`»†*
  7703. @    AddrBlock nodeAddr;         /* node address to be deleted */°dONLNdŒ«Ñ“∂+$
  7704.  
  7705. } MNaddrs;°dONLNd⁄—`‹™(¯~BAddrBlock actNodeAddr;          /* actual node address acquired */°dONLNd€`Ê√*
  7706. GPtr recvRoutine;                /* address of packet receive routine */°dONLNdgÂ`π*
  7707. Eshort reqCableLo;               /* preferred network range for the */°dONLNdÆÔ`˙Ç*
  7708. :short reqCableHi;               /*  node being acquired */°dONLNd͢`∫*
  7709. char reserved[70];°dONLNd˝<á(*Z} MNParamBlock;°dONLNd
  7710. <"Ê*"typedef MNParamBlock*MNParmBlkPtr;°dONLNd0+<6ñ*#ifdef __cplusplus°dONLNdC5<@x*
  7711. extern "C" {°dONLNdP?<JZ*
  7712. #endif°dONLNdWI<Th*
  7713. <pascal OSErr MNAddNode(MNParmBlkPtr thePBptr,Boolean async);°dONLNdïS<^w*
  7714. ?pascal OSErr MNRemoveNode(MNParmBlkPtr thePBptr,Boolean async);°dONLNd÷]<hm*
  7715. =pascal OSErr MNNetWrite(MNParmBlkPtr thePBptr,Boolean async);°dONLNdg<rñ*
  7716. #ifdef __cplusplus°dONLNd(q<|A*
  7717. }°dONLNd*{<ÜZ*
  7718. #endif ¡X¡
  7719. *4(NW 13 - AppleTalk: The Rest of the Story(÷˙47)
  7720.  of 61(ÏZM.NW.AppleTalk2ˇX◊#ˇ ˇˇˇˇ#◊ 
  7721. IR,Times
  7722. .+6-Macintosh Technical Notes /4/˘,
  7723. Courier
  7724.     °dONLNd(?*;pascal OSErr MNAddNode(MNParmBlkPtr thePBptr,Boolean async)°dONLNd<'2*
  7725. {°dONLNd?1<<√+$
  7726. thePBptr->csCode = addNode;°dONLNd\;<F‹*
  7727.  thePBptr->ioRefNum = mppUnitNum;°dONLNd~E<P,*
  7728. 0return (PBControl((ParmBlkPtr)thePBptr, async));°dONLNdØOZ(v6}°dONLNd±cnN*>pascal OSErr MNRemoveNode(MNParmBlkPtr thePBptr,Boolean async)°dONLNdÒmx*
  7729. {°dONLNdÙw<Ç“+$
  7730. thePBptr->csCode = removeNode;°dONLNdÅ<å‹*
  7731.  thePBptr->ioRefNum = mppUnitNum;°dONLNd6ã<ñ,*
  7732. 0return (PBControl((ParmBlkPtr)thePBptr, async));°dONLNdgï†(º6}°dONLNdi©¥D*<pascal OSErr MNNetWrite(MNParmBlkPtr thePBptr,Boolean async)°dONLNd¶≥æ*
  7733. {°dONLNd©Ω<»»+$
  7734. thePBptr->csCode = netWrite;°dONLNd««<“‹*
  7735.  thePBptr->ioRefNum = mppUnitNum;°dONLNdÈ—<‹,*
  7736. 0return (PBControl((ParmBlkPtr)thePBptr, async));°dONLNd€Ê(6}
  7737. °dONLNdÒ˝ß*Now for Pascal programmers:
  7738.     °dONLNd8    c*UNIT MultiNode;°dONLNdHE*
  7739.     INTERFACE°dONLNdR'2,*USES°dONLNdX1<<ˇ+$
  7740. 'MemTypes, QuickDraw, OSIntf, AppleTalk;°dONLNdÄEP1(l6CONST°dONLNdÜYd©*{    MultiNode .MPP csCodes }°dONLNd§mxq*E    netWrite = 261;                 { Send packet through multinode }°dONLNdÍwÇ?*
  7741. ;    addNode = 262;                  { Request a multinode }°dONLNd&Åå0*
  7742. 8    removeNode = 263;               { Remove multinode }°dONLNd_ï†,*TYPE°dONLNddü™Í*
  7743. *MNParmType = (AddNodeParm,RemoveNodeParm);°dONLNdè≥æ§*MNParamBlock = PACKED RECORD°dONLNd¨Ω»0*
  7744. 8    qLink: QElemPtr;                  {next queue entry}°dONLNd«“*
  7745. 2    qType: INTEGER;                   {queue type}°dONLNd—‹*
  7746. 4    ioTrap: INTEGER;                  {routine trap}°dONLNdM€Ê+*
  7747. 7    ioCmdAddr: Ptr;                   {routine address}°dONLNdÖÂ:*
  7748. :    ioCompletion: ProcPtr;            {completion routine}°dONLNd¿Ô˙*
  7749. 3    ioResult: OSErr;                  {result code}°dONLNdÙ˘*
  7750. 2    ioNamePtr: StringPtr;             {->filename}°dONLNd'Ä*
  7751. H    ioVRefNum: INTEGER;               {volume reference or drive number}°dONLNdp
  7752. S*
  7753. ?    ioRefNum: INTEGER;                {driver reference number}°dONLNd∞"è*
  7754. K    csCode: INTEGER;                  {call command code AUTOMATICALLY set}°dONLNd˝!<,Ç+$
  7755. filler1: Byte;°dONLNd
  7756. +<6w*
  7757. ?checkSumFlag: Byte;            { perform checksum on datagram }°dONLNdN5<@r*
  7758. >wdsPointer: Ptr;               { Ptr to write-data structure }°dONLNdé?<Jë*
  7759. filler2: INTEGER;°dONLNd°I<Tñ*
  7760. CASE MNParmType of°dONLNdµS<^Ç*
  7761.   AddNodeParm:°dONLNd≈]<hr*
  7762. >   (reqNodeAddr: AddrBlock;    { preferred address requested }°dONLNdgrv(é6F           actNodeAddr: AddrBlock;    { actual node address acquired }°dONLNdKq|è*
  7763. K           recvRoutine: ProcPtr;      { address of packet receive routine }°dONLNdó{ÜÖ*
  7764. I           reqCableLo: INTEGER;       { preferred network range for the }°dONLNd·ÖêN*
  7765. >           reqCableHi: INTEGER;       {  node being acquired } ¡4¡˘
  7766. **48)
  7767.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇƒ◊#ˇ ˇˇˇˇ#◊ 
  7768. IR,Times
  7769. .+Z-Developer Support Center(-Á January 1993 /X/,
  7770. Courier
  7771.     °dONLNd<(;(DZ3           reserved: PACKED ARRAY [1..70] of Byte);°dONLNd4'<2•*
  7772.       RemoveNodeParm:°dONLNdL1Ñ<í+H
  7773. 6(nodeAddr: AddrBlock);  { node address to be deleted }°dONLNdÉ;<Fd(bZ    END;°dONLNdåO<ZÕ*MNParmBlkPtr = ^MNParamBlock;°dONLNd™c<nÜ*BFUNCTION MNAddNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;°dONLNdÌm<xï*
  7774. EFUNCTION MNRemoveNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;°dONLNd3w<Çã*
  7775. CFUNCTION MNNetWrite(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;°dONLNdwã<ñÇ*IMPLEMENTATION°dONLNdÜü<™Ü*BFUNCTION MNAddNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;°dONLNd…©<¥U*
  7776. BEGIN°dONLNd–≥`æÏ+$
  7777. thePBptr^.csCode := addNode;°dONLNdÓΩ`»*
  7778. !thePBptr^.ioRefNum := mppUnitNum;°dONLNd«`“d*
  7779. 4MNAddNode := PBControl(ParmBlkPtr(thePBptr), async);°dONLNdF—<‹P(¯ZEND;°dONLNdKÂ<ï*EFUNCTION MNRemoveNode(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;°dONLNdëÔ<˙U*
  7780. BEGIN°dONLNdò˘`˚+$
  7781. thePBptr^.csCode := removeNode;°dONLNdπ`*
  7782. !thePBptr^.ioRefNum := mppUnitNum;°dONLNd‹
  7783. `s*
  7784. 7MNRemoveNode := PBControl(ParmBlkPtr(thePBptr), async);°dONLNd<"P(>ZEND;°dONLNd+<6ã*CFUNCTION MNNetWrite(thePBptr: MNParmBlkPtr; async: BOOLEAN): OSErr;°dONLNd]5<@U*
  7785. BEGIN°dONLNdd?`JÒ+$
  7786. thePBptr^.csCode := netWrite;°dONLNdÉI`T*
  7787. !thePBptr^.ioRefNum := mppUnitNum;°dONLNd¶S`^i*
  7788. 5MNNetWrite := PBControl(ParmBlkPtr(thePBptr), async);°dONLNd‹]<hP(ÑZEND;°dONLNd·q<|P*END.
  7789. °dONLNdÊá<ì≥*<Things You Need to Know When Writing a Multinode Application°dONLNd#ü<´Ì*YTwo new .MPP driver control calls have been added to allow multinode applications to add °dONLNd|üÌ´˛(« and°dONLNdÄ´<∑ö(”Zremove multinodes.
  7790. °dONLNdì√<œ¨*AddNode (csCode=262)
  7791. °dONLNd®⁄<Êû*IA user can request an extra node using a control call to the .MPP driver °dONLNdÒ⁄ûÊ˛(ºafter it has opened.°dONLNdÊ<Ú(Z,Only one node is acquired through each call.
  7792. °dONLNd3˛<
  7793. ú*Parameter Block:°dONLNdE    N`+ -->°dONLNdI    my)24°dONLNdL    ñΔ))ioRefNum°dONLNdU    Á)Qshort°dONLNd\    8∞)Q; driver ref. number°dONLNdrN `(<l-->°dONLNdvm y)26°dONLNdyñ ∫))csCode°dONLNdÄÁ )Qshort°dONLNdá8 »)Q; always = AddNode (262)°dONLNd°N+`(Gl-->°dONLNd•m+y)36°dONLNd®ñ+ÿ)) reqNodeAddr°dONLNd¥Á+)Q    AddrBlock°dONLNdæ8+˛)Q!; the preferred address requested°dONLNdÈ*86å* ; by the user.°dONLNd˘5NA`(]l<--°dONLNd˝5mAy)40°dONLNd5ñAÿ)) actNodeAddr°dONLNd 5ÁA)Q    AddrBlock°dONLNd58AÚ)Q; actual node address acquired.°dONLNd7@NL`(hl-->°dONLNd;@mLy)44°dONLNd>@ñLÿ)) recvRoutine°dONLNdJ@ÁLˇ)Qlong°dONLNdP@8L¢)Q; address of the °dONLNda@¢L˛)jreceive routine°dONLNdyK8W¯(sV ; for MPP to call during packet °dONLNd°V8bz* ; delivery.°dONLNdÆaNm`(âl-->°dONLNd≤ammy)48°dONLNdµañm“))
  7794. reqCableLo°dONLNd¿aÁm)Qshort°dONLNd«a8m∂)Q; the preferred range°dONLNd‡lNx`(îl-->°dONLNd‰lmxy)50°dONLNdÁlñx“))
  7795. reqCableHi°dONLNdÚlÁx)Qshort°dONLNd˘l8xº)Q; node being acquired.°dONLNdwNÉ`(ül-->°dONLNdwmÉy)52°dONLNdwñÉfi)) reserved[70]°dONLNd%wÁɡ)Qchar°dONLNd+w8É™)Q; 70 reserved bytes ¡X¡(÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙49)
  7796.  of 61(ÏZM.NW.AppleTalk2ˇí◊#ˇ ˇˇˇˇ#◊ 
  7797. IR,Times
  7798. .+6-Macintosh Technical Notes /4/˘,
  7799. Courier°dONLNd)T*
  7800. AddrBlock:°dONLNd (*4B+ aNet°dONLNd(r4ê)Hshort°dONLNd(4V)¢ ; network #°dONLNd)3*?H([HaNode°dONLNd03r?¿)H
  7801. unsigned chae°dONLNd@3?D)¢; node #°dONLNdJ>*JT(fHaSocket°dONLNdR>rJ¿)H
  7802. unsigned char°dONLNdb>JŒ)¢; should be zero for this call.
  7803. °dONLNdÇVb*(~6The
  7804. °dONLNdÖV*b-) 
  7805. °dONLNdÜU-a^)AddNode°dONLNdçV^b”)1 call must be made as an 
  7806. °dONLNd¶V”b )u    IMMEDIATE
  7807. °dONLNdØV bP)8 control call at °dONLNd¿VPb⁄)Esystem task time. The .MPP°dONLNd€bnP(ä6Bdriver will try to acquire the requested node address. The result °dONLNdbPn⁄(äncode will be returned in the°dONLNd:nzP(ó6ioResult°dONLNdBoP{⁄)8 field in the parameter block. °dONLNdao⁄{⁄)ä4The result code –1021 indicates that the .MPP driver°dONLNdñ|à∞(§6 was unable to continue with the °dONLNd∂{∞á·)òAddNode°dONLNdΩ|·ày)1# call because of the current state °dONLNd‡|yà⁄)òof .MPP. The caller°dONLNdÙâïh(±6should retry the °dONLNdàhîô)PAddNode°dONLNd âôï·)1 call (the retry °dONLNdâ·ïî)H$can be issued immediately after the °dONLNdAàîî≈)≥AddNode°dONLNdHâ≈ï⁄)1 call°dONLNdNï°
  7808. (Ω60failed with error–1021) until a node address is °dONLNd~ï
  7809. °⁄)ı)successfully attained or another error is°dONLNd®°≠C(…6    returned.°dONLNd≤π≈Ã*WIf the requested node address is zero, invalid, or already taken by another machine on °dONLNd    πÃ≈⁄(·Íthe°dONLNd
  7810. ≈—ß(Ì6Inetwork, a random node address will be generated by the .MPP driver. The °dONLNdV≈ß—⁄(Ì≈
  7811. parameters°dONLNda—›^(˙6
  7812. reqCableLo°dONLNdk“^fiu)F and °dONLNdp—u›ª)
  7813. reqCableHi°dONLNdz“ªfiæ)F °dONLNd{“æfiè)/will be used only if there is no router on the °dONLNd™“èfi⁄)—network and all°dONLNd∫flÎà(6the node addresses in °dONLNd–flàÎ2)p the network number specified in °dONLNdfi2Íc)™NetHint°dONLNd˜flcÎ⁄)1 (the last used network°dONLNdΘ˙(6-number stored in parameter RAM) are taken up.°dONLNd=Ø*In this case, the .MPP driver °dONLNd[Ø⁄)ó9tries to acquire a node address from the network range as°dONLNdïX(86
  7814. specified by °dONLNd¢Xû)@
  7815. reqCableLo°dONLNd¨ûπ)F and °dONLNd±πˇ)
  7816. reqCableHi°dONLNdªˇü)F. The network range is defined °dONLNd⁄ü⁄)† by the seed°dONLNdÊ(õ(D6router on a network. If a °dONLNdõ(⁄)ÉAspecific cable range is not important to the application, set the°dONLNdB(4^(Q6
  7817. reqCableLo°dONLNdL)^5y)F and °dONLNdQ(y4») reqCableHi °dONLNd\)»5))Ofields to zero. The °dONLNdp()4v)a recvRoutine°dONLNd{)v5|)M °dONLNd|)|5⁄)is an address of a°dONLNdè5AÀ(]6&routine in the application to receive °dONLNdµ5ÀA⁄)≥5broadcasts and directed packets for the corresponding°dONLNdÎAMK(i6
  7818. multinode.°dONLNdˆeqÄ*$Possible Error Codes:
  7819. °dONLNd
  7820. }*âH+noErr°dONLNd}üâ•)u0°dONLNd}â&)Q    ; success°dONLNd!à*î∫(∞HtryAddNodeAgainErr -1021°dONLNd;àî∞)Δ ; MPP was not able to add node, °dONLNd_ìü8* ; try again.°dONLNdmû*™~(ΔHMNNotSupported°dONLNd|ûü™Ω)u-1022°dONLNdÉû™™)Q; Multinode is not supported by°dONLNdß©µb* ; the current ADEV.°dONLNdº¥*¿ä(‹HnoMoreMultiNodes°dONLNdÕ¥ü¿Ω)u-1023°dONLNd‘¥¿∂)Q!; no node address is available on°dONLNd˙øÀD* ; the network.°dONLNd    ÷‚ù(˛6RemoveNode (csCode=263)
  7821. °dONLNd!Ì˘®*This call removes a multinode °dONLNd?Ì®˘⁄)ê<address and must be made at system task time. Removal of the°dONLNd|˘è(!6user node is not allowed.
  7822. °dONLNdñx*Parameter Block:°dONLNdß*(<+ -->°dONLNd´`(l)624°dONLNdÆÑ(¥)$ioRefNum°dONLNd∑Ã(‰)Hword°dONLNdΩ(å)H; driver ref. number°dONLNd“'*3<(OH-->°dONLNd÷'`3l)626°dONLNdŸ'Ñ3®)$csCode°dONLNd‡'Ã3‰)Hword°dONLNdÊ'3∂)H always = RemoveNode (263)°dONLNd2*><(ZH-->°dONLNd2`>l)636°dONLNd    2Ñ>¥)$NodeAddr°dONLNd2Ã>)H    AddrBlock°dONLNd2>¬)H; node address to be deleted.
  7823. °dONLNd:IUÄ(q6Possible Error Codes:
  7824. °dONLNdPa*mH+noErr°dONLNdVaÑmä)Z0°dONLNdYaÃm)H    ; success°dONLNdcl*xZ(îHparamErr°dONLNdllÑxñ)Z-50°dONLNdqlÃxP)H; bad parameter passed ¡4¡˘(÷650)
  7825.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ¶◊#ˇ ˇˇˇˇ#◊ 
  7826. IR,Times
  7827. .+Z-Developer Support Center(-Á January 1993 /X/°dONLNd<)ñ(EZReceiving Packets
  7828. °dONLNd4<@fl*#Broadcast packets are delivered to °dONLNd64fl@˛)£9both the user’s node and the multinodes on every machine.°dONLNdpA<M?(iZ,If several multinodes are acquired with the     °dONLNdúA?Mc(i]same ,
  7829. Courier°dONLNd°@cL∞)$ recvRoutine°dONLNd¨A∞M˛)M
  7830.  address, the°dONLNd∫M<Yâ(vZ recvRoutine°dONLNd≈NâZC)M', listening for these multinodes, will °dONLNdÏNCZ˛)∫$be called only once in the case of a°dONLNdZ<fé(ÇZbroadcast packet.°dONLNd#r<~|*@Multinode receive handlers should determine the number of bytes °dONLNdcr|~˛(ööalready read into the Read°dONLNd~~<äd(¶Z:Header Area (RHA) by subtracting the beginning address of °dONLNd∏~dä˛(¶Çthe RHA from the value in A3°dONLNd’ä<ñS(≤Z(see °dONLNd⁄äSñ•)Inside Macintosh°dONLNdÍä•ñâ)R/ Volume II, page 326, for a description of the °dONLNdäâñ˛)‰Read Header Area). A3°dONLNd/ñ<¢Y(æZ9points past the last byte read in the RHA. The offset of °dONLNdhñY¢˛(æwRHA from the top of the .MPP°dONLNdÖ£<Ø€(ÀZ#variables is defined by the equate °dONLNd®¢€Æ˛)üToRHA°dONLNd≠£˛Ø)# °dONLNdÆ£Øy)in the MPW include file °dONLNdΔ¢yÆø)x
  7831. ATalkEqu.a°dONLNd–£øØ˛)F
  7832. . The receive°dONLNdfi∞<ºq(ÿZ handler is °dONLNdÈ∞qº≈)5expected to call °dONLNd˙Ø≈ª)T    ReadRest °dONLNd∞º˛)B1to read in the rest of the packet. In the case of°dONLNd5º<»Ì(‰Z#LocalTalk, ReadRest should be done °dONLNdXºÌ»˛)±9as soon as possible to avoid loss of the packet. Register°dONLNdí…<’…(ÒZA4 contains the pointer to the °dONLNd±»…‘)ç ReadPacket °dONLNdº…’*)Mand °dONLNd¿»*‘i)    ReadRest °dONLNd……i’“)?routines in the ADEV.°dONLNdfl·<Ì‘(    Z"To read in the rest of the packet,°dONLNd˘Ñô+HJSR°dONLNd˘®À)$2(A4)°dONLNd<h(9Z    On entry:°dONLNd`)n+$
  7833. A3°dONLNdÑ**)$%pointer to a buffer to hold the bytes°dONLNdC*`6n(S~D3°dONLNdF+Ñ7º)$Asize of the buffer (word), which can be zero to throw away packet°dONLNdàC<Oa(kZOn exit:°dONLNdíO`[n+$
  7834. D0°dONLNdïPÑ\Æ)$modified°dONLNdü\`hn(Ö~D1°dONLNd¢]ÑiÆ)$modified°dONLNd¨i`un(í~D2°dONLNdØjÑv≤)$    preserved°dONLNd∫v`Çn(ü~D3°dONLNdΩwÑÉÒ)$OEquals zero if requested number of bytes was read; is less than zero if packet °dONLNdÉÑè«* Gwas –D3 bytes too large to fit in buffer and was truncated; is greater °dONLNdUÉ«è˛(´ than zero if°dONLNddèÑõF(∑¢)D3 bytes were not read (packet is smaller°dONLNdëõÑߺ* than buffer)°dONLNdüß`≥n(–~A0°dONLNd¢®Ñ¥≤)$    preserved°dONLNd≠¥`¿n(›~A1°dONLNd∞µÑ¡≤)$    preserved°dONLNdª¡`Õn(Í~A2°dONLNdæ¬ÑŒ≤)$    preserved°dONLNd…Œ`⁄n(˜~A3°dONLNdÜр;)$*pointer to 1 byte after the last byte read°dONLNd˜Ë<Ùq(Z    For more °dONLNdËqÙ–)5information about °dONLNdÁ–Û!)_ ReadPacket °dONLNdË!Ù9)Qand °dONLNd!Á9Ûq)ReadRest°dONLNd)ËqÙ©)8 , refer to °dONLNd4Ë©Ù˛)8Inside Macintosh°dONLNdEÙ<¢(ZVolume II, page 327.°dONLNd\
  7835. <>*8A user can determine if a link is extended by using the °dONLNdî >Æ(5\GetAppleTalkInfo°dONLNd§
  7836. ÆÏ)p control call. °dONLNd≥
  7837. Ï˛)>The°dONLNd∑<%ü(BZConfiguration °dONLNd≈ü&)cfield returned by this °dONLNd‹&˛)i2call is a 32-bit word that describes the AppleTalk°dONLNd&<2Å(NZDconfiguration. Bit number 15 (0 is LSB) is on if the link in use is °dONLNdS&Å2·(Nüextended. Refer to °dONLNdf&·2˛)`Inside°dONLNdm2<>p(ZZ
  7838. Macintosh °dONLNdw2p>‰)4Volume VI, page 32-15.°dONLNdéJ<V (rZ$Sending Datagrams Through Multinodes°dONLNd≥c<o*(To send packets through multinodes, use °dONLNd€coø)„the new .MPP control call, °dONLNdˆbøn˛)†    NetWrite.°dONLNdo<{t(òZNetWrite°dONLNdpt|›)8 allows the owner of °dONLNdp›|c)ithe multinode to specify a °dONLNd8pc|Ì)Üsource network, node, °dONLNdNpÌ|˛)äand°dONLNdR|<àd(§Zsocket °dONLNdY|dà˙)(from which to send a datagram. ¡X¡
  7839. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙51)
  7840.  of 61(ÏZM.NW.AppleTalk2ˇ:◊#ˇ ˇˇˇˇ#◊ 
  7841. IR,Times
  7842. .+6-Macintosh Technical Notes /4/˘°dONLNd)ä*NetWrite (csCode=261),
  7843. Courier°dONLNd4@x*Parameter Block:°dONLNd(?*K<+ -->°dONLNd,?WKc)-26°dONLNd/?ÑK®)-csCode°dONLNd6?fiKˆ)Zword°dONLNd;?Kû)6; always NetWrite (261)°dONLNdTJ*V<(rH-->°dONLNdXJWVc)-29°dONLNd[JÑVÃ)- checkSumFlag°dONLNdhJfiVˆ)Zbyte°dONLNdmJVn)6; checksum flag°dONLNd~U*a<(}H-->°dONLNdÇUWac)-30°dONLNdÖUÑa¿)-
  7844. wdsPointer°dONLNdêUfia)Zpointer°dONLNdòUaò)6; write data structure
  7845. °dONLNdØlxÄ(î6Possible Error Codes:
  7846. °dONLNdΔÑ*êH+noErr°dONLNdÕÑÑêä)Z0°dONLNd–ÑÃê)H    ; success°dONLNd€è*õ`(∑H    ddpLenErr°dONLNdÂèÑõñ)Z-92°dONLNdÍèÃõb)H; datagram length too big°dONLNdö*¶l(¬H noBridgeErr°dONLNdöѶñ)Z-93°dONLNdöö2)H; no router found°dONLNd)•*±x(ÕH
  7847. excessCollsns°dONLNd7•ѱñ)Z-95°dONLNd<•ñÜ)H; excessive collisions on write
  7848. °dONLNd\Ω…¶(Â6!This call is very similar to the °dONLNd}º¶»fi)éWriteDDP°dONLNdÖΩfi…ù)8* call. The key differences are as follows:°dONLNd∞’*·.(˝H•°dONLNd≤’7·R)
  7849. ;The source socket is not specified in the parameter block. °dONLNdÌ’R·⁄(˝pInstead it is specified along°dONLNd ·7ÌÁ(    U#with the source network number and °dONLNd.·ÁÌ⁄)∞0source node address in the DDP header pointed to°dONLNd_Ì7˘—(UUby the write-data structure (WDS). Furthermore, the socket need not be opened. Refer °dONLNd¥Ì—˘⁄(Ôto°dONLNd∑˘7ã(!UInside Macintosh °dONLNd»˘ãQ)T*Volume II, page 310, for a description of °dONLNdÚ˘Q⁄)Δthe write-data structure. It is°dONLNd7W(-U@important to note that the caller needs to fill in the WDS with °dONLNdRW⁄(-uthe source network, source°dONLNdm7À(9UUnode, and source socket values. .MPP does not set these values for the NetWrite call.°dONLNdƒ**6.(RH•°dONLNdΔ*76L)
  7850. The °dONLNd )L5†) checkSumFlag°dONLNd÷*†6£)T °dONLNd◊*£6⁄)Cfield has a slightly different meaning. If true (nonzero), then the°dONLNd67B|(^UCchecksum for the datagram will be calculated prior to transmission °dONLNd^6|B⁄(^öand placed into the°dONLNdrB7Ns(jU DDP header °dONLNd}BsN-)<)of the packet. If false (zero), then the °dONLNd¶B-NÕ)∫checksum field is left alone°dONLNd¬BÕN⁄)† in°dONLNdΔN7Z§(vUMthe DDP header portion of the packet. Thus if a checksum is already present, °dONLNdN§Z⁄(v¬ it is passed°dONLNd Z7f£(ÇUHalong unmodified. For example, the AppleTalk Remote Access program sets °dONLNdhZ£f⁄(Ç¡
  7851. this field to°dONLNdvf7rP(éU=zero, since remote packets that it passes to the .MPP driver °dONLNd≥fPr⁄(énalready have valid checksum°dONLNdœr7~T(öU=fields. Finally, if the application desires no checksum, the °dONLNd rT~⁄(örchecksum field in the DDP°dONLNd&~7ä(¶U-header in the WDS header must be set to zero.°dONLNdTñ¢Å(æ6Datagrams sent with °dONLNdhñÅ¢¬)ithis call are °dONLNdvñ¬¢Ñ)A#always sent using a long DDP header°dONLNdôñÑ¢Ω)¬ . Refer to °dONLNd§ñΩ¢⁄)9Inside°dONLNd´¢ÆI( 6    AppleTalk°dONLNd¥¢IÆx)1    , second °dONLNdΩ¢xÆ⁄)/Dedition, page 4-16, for a description of the DDP header. Even if the°dONLNdÆ∫Ã(÷6Wdestination node is on the same LocalTalk network, a long DDP datagram is used so that °dONLNdYÆÃ∫⁄(÷Íthe°dONLNd]∫Δj(‚6Fsource information can be specified. The LAP header source node field °dONLNd£∫jΔ⁄(‚àwill always be equal to°dONLNdªΔ“ÿ(Ó6\the user node address (sysLapAddr), regardless of the source node address in the DDP header.°dONLNdfiÍT*0AppleTalk Remote Access Network Number Remapping°dONLNdIˆ≥*PNetwork applications should be careful not to pass network numbers as data in a °dONLNdôˆ≥⁄(—network°dONLNd°h(*6>transaction. AppleTalk Remote Access performs limited network °dONLNdflh⁄(*Ünumber remapping. If°dONLNdÙ(662network numbers are passed as data, they will not °dONLNd    &⁄)¯%get remapped. AppleTalk Remote Access°dONLNd    L&Ê(B6&recognizes network numbers in the DDP °dONLNd    rÊ&⁄)Œ.header and among the various standard protocol°dONLNd    °&2”(N6#packets, NBP, ZIP, RTMP, and so on.°dONLNd    ≈>J›*!Is There a Router on the Network?°dONLNd    ÁVbè*Do not assume that there °dONLNd
  7852. Vèb⁄)wBare no routers on the network if your network number is zero. With°dONLNd
  7853. Cbnu(ä6EAppleTalk Remote Access, you can be on network zero and be connected °dONLNd
  7854. àbun⁄(äìto a remote network.°dONLNd
  7855. ùo{¶(ó6Network applications should °dONLNd
  7856. πo¶{Œ)éuse the °dONLNd
  7857. ¡nŒz)( GetZoneList°dONLNd
  7858. Ão{B)M or the °dONLNd
  7859. ‘nBz≤)'GetBridgeAddress°dONLNd
  7860. ‰o≤{⁄)p     calls to°dONLNd
  7861. Ó{áÍ(£6.determine if there is a router on the network. ¡4¡˘
  7862. *352)
  7863.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇx◊#ˇ ˇˇˇˇ#◊ 
  7864. IR,Times
  7865. .+Z-Developer Support Center(-Á January 1993 /X/
  7866. °dONLNd)<8Û(TZNew for AppleTalk ADEVs
  7867. °dONLNdD<P¿*PFirst, a word from our sponsors: The information in this section is provided to °dONLNdiD¿P˛(lfi assist ADEV°dONLNduP<\Ó(xZ&developers in updating their products °dONLNdõPÓ\˛)≤6for compatibility with AppleTalk Remote Access. If you°dONLNd“\<h|(ÑZCare a Ethernet or token ring developer, MacDTS strongly urges that °dONLNd\|h˛(Ñöyou consider following the°dONLNd0h<t (êZ(Multivendor ADEV Architecture described °dONLNdXh t˛)œ2earlier. For developers of Fiber Data Distribution°dONLNdãt<Äc(úZ9Interface (FDDI) network interface cards, please contact °dONLNdƒtcIJ(úÅApple Software Licensing for°dONLNd·Ä<åë(®ZDinformation on licensing the new FDDI Phase 2 ADEV and Driver shell.°dONLNd'ò<§f*=Several new calls have been implemented into the .MPP driver °dONLNddòf§˛(¿Ñfor AppleTalk version 57. Two°dONLNdÇ•<±Z(ÕZcalls, ,
  7868. Courier°dONLNdâ§Z∞Ü)AOpen °dONLNdè•ܱú),and °dONLNdì§ú∞Δ)AClose°dONLNdô•Δ±ã)*', were built into AppleTalk version 54 °dONLNd¿•ã±˛)≈and later, and are also°dONLNdÿ±<Ω≤(ŸZdocumented here. These °dONLNdÔ±≤Ω˛)vDcalls notified the ADEV of changes in the status of the .MPP driver.°dONLNd4æ< Ù(ÊZ$For AppleTalk version 57, three new °dONLNdXæÙ )∏calls, °dONLNd_Ω…Q)    AAddNode,°dONLNdhæQ V)? °dONLNdiΩV…é)ADelNode°dONLNdqæé ≠)8, and °dONLNdwΩ≠…˙) AGetNodeRef°dONLNdÇæ˙ ˛)M,°dONLNdÑÀ<◊´(ÛZplus a change to the °dONLNdô ´÷Ì)o    AGetInfo °dONLNd¢ÀÌ◊f)Bcall, were implemented °dONLNdπÀf◊˛)yto support the Multiple Node°dONLNd÷◊<„y(ˇZ
  7869. Architecture.°dONLNd‰Ô<˚Q*5With the release of AppleTalk version 58, support is °dONLNdÔQ˚˛(oprovided for the Simple Network°dONLNd9˚<}(#Z Management °dONLNdD˚}˛)AEProtocol (SNMP), and for the new Router Manager product. Programmer’s°dONLNdä<b(/ZGuides °dONLNdëb˛)&Ofor each of these products are available from APDA. For all ADEVs, an important°dONLNd·<`(;Z=change is required for the Router Manager product to provide °dONLNd`˛(;~basic SNMP support. An ADEV°dONLNd:<+(GZ+must be modified to support a minor change °dONLNde+˛)”.in the AGetInfo call. The ADEV must respond to°dONLNdî+<7(SZYthe AGetInfo call by returning the slot number of the network device being supported, in °dONLNdÌ+7˛(Sthe°dONLNdÒ7<Cfi(_ZUsecond reserved byte. This change is required so that when queried by a console, the °dONLNdF7fiC˛(_¸Router°dONLNdMC<O◊(kZPManager can report the slot number of the connection being supported. For those °dONLNdùC◊O˛(kınetwork°dONLNd•O<[(wZ)devices running via the LocalTalk ports, °dONLNdŒO[˛)«2the second reserved byte should continue to return°dONLNd[<g>(ÉZ6zero. There is no support for such ADEVs at this time.°dONLNd8s<>*4EtherTalk Phase 2, version 2.3, and TokenTalk phase °dONLNdls>˛(õ\'2, version 2.4, drivers support the new°dONLNdî<ãΔ(ßZPMultiple Node Architecture. Both drivers and AppleTalk version 57 are available °dONLNd‰Δã˛(߉ through the°dONLNdã<ó(≥Z)Network Software Installer, version 1.1. °dONLNdãó˛)≈1As mentioned previously, AppleTalk version 57 and°dONLNdKó<£Y(øZthese °dONLNdQóY£˛)Rdrivers are compatible with system software version 6.0.5 and later. Note that the°dONLNd§£<Ø(ÀZ-AppleTalk Remote Access product includes the °dONLNd—£ØÔ)·+EtherTalk Phase 2, version 2.3 driver, but °dONLNd¸£ÔØ˛)“not°dONLNd    Ø<ªÈ(◊ZXthe multinode-compatible TokenTalk Phase 2, version 2.4, driver. Token ring developers, °dONLNd    XØÈª˛(◊who°dONLNd    \ª<«°(„ZKlicense TokenTalk Phase 2, version 2.2 and earlier, should contact Apple’s °dONLNd    ßª°«˛(„øSoftware Licensing°dONLNd    ∫«<”t(ÔZ department.°dONLNd    Δfl<Îc*8The following information describes changes to the ADEV °dONLNd    ˛flcβ(Åthat are required for multinode°dONLNd
  7870. Î<˜H(Z:compatibility. This information is of specific importance °dONLNd
  7871. XÎH˜˛(f"to developers of custom ADEVs. The°dONLNd
  7872. {˜<%(Z/ADEV can be expected to function under version °dONLNd
  7873. ™˜%‘)È"6.0.5 and later. A version 3 ADEV °dONLNd
  7874. Ø‘Ô)Ømust°dONLNd
  7875. –˜Ô˛) be°dONLNd
  7876. ‘<L(+Z7used with AppleTalk version 57 or later. Developers of °dONLNd L˛(+j!custom ADEVs will want to contact°dONLNd -<4(7Z3Software Licensing to license AppleTalk version 57.°dONLNd a'<3x*CFor compatibility with Multinode AppleTalk, the 'atlk' resource of °dONLNd §'x3˛(Oñan ADEV must be modified°dONLNd Ω3<?Ä([Zto respond to °dONLNd À3Ä?˛)DIthese calls as described below. To determine whether an ADEV is multinode°dONLNd ?<Kˆ(gZYcompatible, the .MPP driver makes an AGetInfo call to determine whether the ADEV version °dONLNd n?ˆK˛(gis°dONLNd qK<W)(sZ03 or later. Any ADEVs responding with a version °dONLNd °K)W˛)Ì,of 3 or later must be prepared to respond to°dONLNd ŒX<dÇ(ÄZthe new calls: °dONLNd ›WÇc∫)FAAddNode°dONLNd ÂX∫d¬)8, °dONLNd ÁW¬c˙)ADelNode°dONLNd ÔX˙d)8, °dONLNd ÒXd)and °dONLNd ıWce) AGetNodeRef°dONLNd
  7877. Xedó)M
  7878. . See the °dONLNd
  7879. Xód˛)2Macintosh AppleTalk°dONLNd
  7880. d<pfi(åZConnections Programmer’s Guide°dONLNd
  7881. <dfipÓ)¢6 for more information about writing an AppleTalk ADEV.°dONLNd
  7882. s|<àx(§Z The desired °dONLNd
  7883. |xà˛)<Narchitecture for a multinode-compatible ADEV is such that it delivers incoming°dONLNd
  7884. Œà<î.(∞Z1packets to the LAP Manager along with an address °dONLNd
  7885. ˇà.î˛)Ú%reference number, AddrRefNum. The LAP ¡X¡
  7886. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙53)
  7887.  of 61(ÏZM.NW.AppleTalk2ˇ≤◊#ˇ ˇˇˇˇ#◊ 
  7888. IR,Times
  7889. .+6-Macintosh Technical Notes /4/˘
  7890. °dONLNd)Ω*Manager uses the AddrRefNum to °dONLNdΩ)⁄)•=locate the correct receive routine to process the packet. For°dONLNd])5´(Q6Ubroadcast packets, the LAP Manager handles multiple deliveries of the packet to each °dONLNd≤)´5⁄(Q…    multinode°dONLNdº5Aa(]6receive routine.°dONLNdÕMYh*BThe .MPP driver for AppleTalk version 57 supports the new control °dONLNdMhY⁄(uÜcall to add and remove°dONLNd&Yeª(Å6Smultinodes, along with the network write call that allows the specification of the °dONLNdyYªe⁄(ÅŸsource°dONLNdÄeq[(ç6Eaddress. .MPP includes a modification in its write function to check °dONLNd≈e[q⁄(çyfor one multinode sending°dONLNdflq}ö(ô6Oto another. .MPP supports intermultinode transmission within the same machine. °dONLNd.qö}⁄(ô∏ For example,°dONLNd;}âë(•6Nthe user node may want to send a packet to a multinode within the same system.°dONLNdäï°z*AGetInfo (D0=3)°dONLNdö≠πF*;The AGetInfo call should be modified to return the maximum °dONLNd’≠Fπ~(’d
  7891. number of °dONLNdfl≠~πæ)8
  7892. AppleTalk °dONLNdÈ≠æπ⁄)@nodes°dONLNdÔπ≈“(·6'that can be provided by the atlk. This °dONLNdπ“≈⁄)∫3limit will be used by .MPP to control the number of°dONLNdJ≈—ù(Ì6Rmultinodes that can be added on a single machine. The new interface is as follows:°dONLNdù›È.*Call:°dONLNd§›`Èí)H    D1 (word)°dONLNdÆ›®È=)H!length (in bytes) of reply buffer°dONLNd“È`ı(~A1 -> °dONLNd⁄È®ı?)H Pointer to GetInfo record buffer°dONLNd˚ı;(6Return:°dONLNdı`|)HA1 ->°dONLNd
  7893. ı®)HPointer to GetInfo record°dONLNd&`
  7894. n()~D0°dONLNd*®
  7895. S)H&nonzero if error (buffer is too small),
  7896. Courier
  7897.     °dONLNdR<'†(CZAGetInfoRec = RECORD°dONLNdg&1'(M6<--°dONLNdk&<1d)$version:°dONLNdu&®1–)lINTEGER;°dONLNd~&1r)H{ version of ADEV, set to °dONLNdò&r1ê)Çthree°dONLNdù&ê1Æ) (3) }°dONLNd§0;'(W6<--°dONLNd®0<;_)$length:°dONLNd±0®;–)lINTEGER;°dONLNd∫0;ö)H"{ length of this record in bytes }°dONLNd›:E'(a6<--°dONLNd·:<EZ)$speed:°dONLNdÍ:®E–)lLongInt;°dONLNdÛ:EÅ)H{ speed of link in bits/sec }°dONLNdDO'(k6<--°dONLNdD<On)$
  7898. BandWidth:°dONLNd!D®O¡)lByte;°dONLNd(DO|)H{ link speed weight factor }°dONLNdENY'(u6<--°dONLNdIN<Yi)$    reserved:°dONLNdTN®Y¡)lByte;°dONLNd[NY;)H{ set to zero }°dONLNdkXc'(6<--°dONLNdoX<c†)$slot:               °dONLNdÑX®c¡)lByte;°dONLNdãXcê)H { device slot number or zero for°dONLNd≥bmO*
  7899. ( LocalTalk ports }°dONLNd«lw'(ì6<--°dONLNdÀl<wi)$    reserved:°dONLNd÷l®w¡)lByte;°dONLNd›lw;)H{ set to zero }°dONLNdÌvÅ'(ù6<--°dONLNdÒv<ÅZ)$flags:°dONLNd˙v®Å¡)lByte;°dONLNdvÅ1)H
  7900. { see below }°dONLNdÄã'(ß6<--°dONLNdÄ<ã})$
  7901. linkAddrSize:°dONLNd"Ä®ã¡)lByte;°dONLNd)Äãm)H{ of link addr in bytes }°dONLNdCäï'(±6<--°dONLNdGä<ïx)$ linkAddress:°dONLNdUä®ï )lARRAY[0..5] OF Byte;°dONLNdjîü'(ª6<--°dONLNdnî<ül)$maxnodes°dONLNdvîlüv)0: °dONLNdzî®ü–)<INTEGER;°dONLNdÑû<©P(≈ZEND;°dONLNdä≤<ΩZ*flags:°dONLNdë≤`ΩZ)$2bit 7 = 1 if this is an extended AppleTalk, else 0°dONLNdΔº`«¥*
  7902. Dbit 6 = 1 if the link is used for a router-only connection (reserved°dONLNdΔÑ—Ÿ+$
  7903. for half-routing)°dONLNd"–`€Ò(˜~bit 5 through 0 reserved, = 0
  7904. °dONLNd@ÊÚP(6maxnodes°dONLNdHÁPÛ≠)8 is the total number °dONLNd]Á≠Û⁄)];of nodes (user node and multinodes) the ADEV supports. If a°dONLNdôÙˇ(6/version 3 ADEV does not support multinodes, it °dONLNd»Ùˇ{)Ámust return 0 or 1 in the °dONLNd‚Û{ˇ≥)|maxnodes°dONLNdÍÙ≥∏)8 °dONLNdÎÙ∏⁄)field in°dONLNdÙ e()6 AGetInfoRec°dONLNdˇe
  7905. ƒ)M and the ADEV will °dONLNdƒ
  7906. ⁄)_7not be called to acquire multinodes. The version 3 ADEV°dONLNdJ
  7907. ö(56Qwill be called by .MPP in one of the following two ways to acquire the user node:°dONLNdú&*2M+    • If the °dONLNd•&M2‡)#ADEV returns a value of 0 in °dONLNd¬%‡1)ìmaxnodes°dONLNd &2⁄)8(, .MPP will issue Lap Write calls to the°dONLNdÛ27>K(ZU7ADEV with D0 set to $FF indicating that ENQs should be °dONLNd    *2K>⁄(Zisent to acquire the user node.°dONLNd    I>7JQ(fU8.MPP is responsible for retries of ENQs to make sure no °dONLNd    Å>QJ⁄(foother nodes on the network°dONLNd    úJ7Vå(rUalready have this °dONLNd    ÆJåV⁄)U?address. This was the method .MPP used to acquire the user node°dONLNd    ÓV7b&(~U/before multinodes were introduced. This method °dONLNd
  7908. V&b⁄)Ô"of sending ENQs must be available,°dONLNd
  7909. @b7nú(äUeven though the new 
  7910. °dONLNd
  7911. TbúnΔ)eAAddNode
  7912. °dONLNd
  7913. \bΔn…)* °dONLNd
  7914. ]b…n⁄)9call is provided, to allow older versions of AppleTalk to°dONLNd
  7915. ón7z˛(ñU(function properly with a version 3 ADEV. ¡4¡˘
  7916. (÷654)
  7917.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇp◊#ˇ ˇˇˇˇ#◊ 
  7918. IR,Times
  7919. .+Z-Developer Support Center(-Á January 1993 /X/
  7920. °dONLNdN*(Fl&• If the ADEV returns a value of 1 in ,
  7921. Courier°dONLNd&)?)πmaxnodes°dONLNd.?*G)8, °dONLNd0G*s)the new °dONLNd8s)´),AAddNode°dONLNd@´*˛)8 function will be°dONLNdR*[6(Ry(called by .MPP to acquire the user node.°dONLNd{C<O(kZ.For values of maxnode greater than 1, the new °dONLNd©BNS)flAAddNode°dONLNd±CSOV)8 °dONLNd≤CVO˛)"function will be called by .MPP to°dONLNd’O<[€(wZ"acquire the additional multinodes.°dONLNd¯g<sß*AAddNode (D0=9)°dONLNd<ã[*>This is a new call that is used to request the acquisition of °dONLNdF[ã˛(ßy an AppleTalk node address. It is°dONLNdgå<ò((¥Z2called by the .MPP driver during the execution of °dONLNdôå(ò:)Ïthe °dONLNdùã:ók)AddNode°dONLNd§åkò˛)1  control call mentioned earlier.°dONLNd≈ò<§r(¿Z9The ADEV is responsible for retrying enough ENQs to make °dONLNd˛òr§˛(¿êsure no other nodes on the°dONLNd§<∞”(ÃZTnetwork already have the address. .MPP makes this call only during system task time.°dONLNdn¿<ÃU*Call: °dONLNdvøÑÀ†)HA0->°dONLNd|¿ÃÃH)HPointer to parameter block°dONLNdóÕ<Ÿb(ıZReturn: °dONLNd†ÃÑÿô)HD0 °dONLNd•Õßô)H+= zero if address was acquired successfully°dONLNd’ŸÃÂõ* +≠ zero if no more addresses can be acquired
  7922. °dONLNdÒ`˝ñ(~    atlkPBRec°dONLNd
  7923. ÒÃ˝)lRecord°dONLNdÒ˝>)HcsParam°dONLNd¸<N($Z-->°dONLNd ¸`ä)$NetAddr°dONLNd)¸Ã‰)lDS.L°dONLNd.¸ˆ)$1°dONLNd0¸¯)$&; offset 0x1C  24-bit node address to °dONLNd\J*     ; acquire°dONLNdf<N(:Z-->°dONLNdj`ä)$NumTrys°dONLNdsÉ)lDS.W°dONLNdxˆ)$1°dONLNdzÚ)$%; offset 0x20  # of tries for address°dONLNd†<)N(EZ-->°dONLNd§`)ä)$DRVRPtr°dONLNd≠Ã)‰)lDS.L°dONLNd≤)ˆ)$1°dONLNd¥)Œ)$; offset 0x22  ptr to .MPP vars°dONLNd‘(<4N(PZ-->°dONLNdÿ(`4ú)$
  7924. PortUsePtr°dONLNd‰(Ã4‰)lDS.L°dONLNdÈ(4ˆ)$1°dONLNdÎ(4Ê)$#; offset 0x26  ptr to port use byte°dONLNd3<?N([Z-->°dONLNd3`?ú)$
  7925. AddrRefNum°dONLNd3Ã?‰)lDS.W°dONLNd$3?ˆ)$1°dONLNd&3? )$; °dONLNd(3 ?˛) $offset 0x2A  address ref number used°dONLNdS>JJ(f2    ; by .MPP°dONLNd^I`Ux(q~EndR
  7926. °dONLNdc`<lÀ(àZThe offset values describe the °dONLNdÇ`Àl˛)è@location of the fields from the beginning of the parameter block°dONLNd√m<yb(ïZpointed °dONLNdÀmby)&to by 
  7927. °dONLNd—myã)A0
  7928. °dONLNd”mãyì) . °dONLNd’lìx⁄)
  7929. atlkPBRec °dONLNdflm⁄y˛)G<is the standard parameter block record header for a _Control°dONLNdz<ÜÉ(¢Zcall. The field °dONLNd,yÉÖ¥)GNetAddr°dONLNd3z¥Ü∏)1 °dONLNd4z∏Ü+)is the 24-bit AppleTalk °dONLNdLz+ܲ)s)node address that should be acquired. The°dONLNdvá<ì(ØZ-node number is in the least significant byte °dONLNd£áì )Ã0 of °dONLNd®Ü íQ)NetAddr°dONLNdØáQì˛)1". The network number is in bytes 1°dONLNd“î<†i(ºZ    and 2 of °dONLNd€ìiüö)-NetAddr°dONLNd‚îö†˘)1; byte 3 is unused. °dONLNdˆì˘ü*)_NumTrys°dONLNd˝î*†ö)1 is the number of tries °dONLNdîö†˛)pthe atlk should send°dONLNd*†<¨ß(»ZHAARP probes on non-LocalTalk networks to verify that the address is not °dONLNdr†ß¨˛(»≈in use by another°dONLNdÑ≠<πp(’Z entity. On °dONLNdè≠pπŸ)4LocalTalk networks, °dONLNd£¨Ÿ∏
  7930. )iNumTrys°dONLNd™≠
  7931. π˛)1. x 32 number of ENQs will be sent to verify an°dONLNdŸπ<≈d(·Zaddress.°dONLNd„—<›m*DRVRPtr°dONLNdÍ“mfiÑ)1 and °dONLNdÔ—Ñ›“) PortUsePtr °dONLNd˙““fi˛)N>are normally passed when the atlk is called to perform a write°dONLNd9fl<ÎÅ(ZAfunction. For ADEVs that support multinodes, AppleTalk calls the °dONLNdzflÅÎö(ünew °dONLNd~fiöÍ“)AAddNode°dONLNdÜfl“β)8     function°dONLNdêÎ<˜(ZSrather than the write function in the ADEV to send ENQs to acquire nodes. However, °dONLNd„Î˜˛(the°dONLNdÁ¯<]( Zvalues °dONLNdÓ˜]é)!DRVRPtr°dONLNdı¯é•)1 and °dONLNd˙˜•Ú) PortUsePtr °dONLNd¯Ú)M
  7932. are still °dONLNd¯˛)%.required for the ADEV to function properly and°dONLNd><p(-Z are passed °dONLNdIpè)4to the °dONLNdPèœ)    AAddNode °dONLNdYœÁ)@call. °dONLNd_Á-)
  7933. AddrRefNum°dONLNdi-1)F °dONLNdj1˛)(is a reference number passed in by .MPP.°dONLNdì<ã(9ZAThe ADEV must store each reference number with its corresponding °dONLNd‘ã˛(9©multinode address. The°dONLNdÎ<)ä(EZGuse of the reference number is described in the following two sections.°dONLNd    36<BQ*6For multinode-compatible ADEVs, .MPP issues the first °dONLNd    i5QAë(^o    AAddNode °dONLNd    r6ëBÍ)@call to acquire the °dONLNd    Ü6ÍB˛)Yuser°dONLNd    ãC<Oq(kZ
  7934. node. The °dONLNd    ïBqN∑)5
  7935. AddrRefNum°dONLNd    üC∑OM)F associated with the user node °dONLNd    æCMO˛)ñ"must be 0xFFFF. It is important to°dONLNd    ·P<\™(xZassign 0xFFFF as the °dONLNd    ˆO™[)n
  7936. AddrRefNum°dONLNd
  7937. P\∏)F( of the user node, and to disregard the °dONLNd
  7938. (O∏[˛)»
  7939. AddrRefNum°dONLNd
  7940. 3]<it(ÖZ
  7941. passed by °dONLNd
  7942. =]tiΔ)8=.MPP for the user node. See the discussion at the end of the °dONLNd
  7943. z\Δh˛(Ö‰ADelNode°dONLNd
  7944. Éi<ut(ëZ description. ¡X¡
  7945. *E(NW 13 - AppleTalk: The Rest of the Story(÷˙55)
  7946.  of 61(ÏZM.NW.AppleTalk2ˇ∞◊#ˇ ˇˇˇˇ#◊ 
  7947. IR,Times
  7948. .+6-Macintosh Technical Notes /4/˘
  7949. °dONLNd)Ü*ADelNode (D0=10)°dONLNd5Aã*LThis is a new call that is used to remove an AppleTalk node address. It can °dONLNd]5ãA⁄(]©be called by the°dONLNdnAMj(i6E.MPP driver to process the RemoveNode control call mentioned earlier.°dONLNd¥\h1*Call: °dONLNdª\<h^)$   A0->°dONLNd√\Ñh)HPointer to parameter block
  7950. °dONLNd·hÑt§* NetAddr
  7951. °dONLNdËh§t^) ( contains the node address to be deleted°dONLNdtÄX(ú6Return:    D0 °dONLNd!tÑÄG)l)= zero if address is removed successfully°dONLNdNÄÑå*  ≠ zero if address does not exist,
  7952. Courier°dONLNdråÑòk*
  7953. !atlkPBRec.AddrRefNum = AddrRefNum°dONLNdìçkôz)Á to °dONLNdóçzô⁄)be used by .MPP if°dONLNd≠ôÑ•(¡¢the operation is successful
  7954. °dONLNd ±*Ω`(ŸH    atlkPBRec°dONLNd‘±rΩñ)HRecord°dONLNd€±ÃΩˆ)ZcsParam°dONLNd„º»*(‰6-->°dONLNdÁºr»ú)ZNetAddr°dONLNdԺû‰)ZDS.L°dONLNdÙº»)61°dONLNdˆº»∂) offset 0x1C  24-bit node °dONLNd«”Ü* ; address to remove°dONLNd*“fi*(˙6<--°dONLNd.“rfiÆ)Z
  7955. AddrRefNum°dONLNd9“Ãfi‰)ZDS.W°dONLNd>“fi)61°dONLNd@“fi∞); offset 0x2A  AddrRefNum °dONLNd_›Èû* ; passed in by AAddNode°dONLNd|ËÙV* ; on return°dONLNdäÛrˇä(êEndR
  7956. °dONLNdè E(36
  7957. The field °dONLNdô
  7958. Ev)-NetAddr°dONLNd† v))1& is the 24-bit AppleTalk node address °dONLNdΔ )⁄)≥#that should be removed. As with the°dONLNdÍ#X(@6    AAddNode °dONLNdÛX$é)@@selector, the node number is in the least significant byte 0 of °dONLNd3é#ø(@¨NetAddr°dONLNd:ø$⁄)1. The°dONLNd@%1¿(M6!network number is in bytes 1 and °dONLNda%¿1⁄)®2 of °dONLNdf$⁄0 )NetAddr°dONLNdm% 1⁄)1); byte 3 is unused. The address reference°dONLNdó2>C(Z6number, °dONLNdü1C=â)+
  7959. AddrRefNum°dONLNd©2â>Ï)F, associated with the °dONLNdø1Ï=)cNetAddr°dONLNdΔ2>Ç)1, must be returned to °dONLNd‹2Ç>⁄)e.MPP in order for°dONLNdÓ>JR(f6B.MPP to clean up its data structures for the removed node address.°dONLNd1Vb)*As °dONLNd4V)b⁄)Smentioned above, a value of 0xFFFF must be returned to .MPP after deleting the user°dONLNdàbn–(ä6$node. When the AppleTalk connection °dONLNd¨b–n⁄)∏8is started up for the first time on an extended network,°dONLNdÂo{ï(ó6the ADEV can expect to °dONLNd¸oï{–)} process an 
  7960. °dONLNdo–{˙);AAddNode
  7961. °dONLNdo˙{¢)*  request followed shortly by an °dONLNd/n¢z⁄)®ADelNode°dONLNd8{á{(£6request. This results °dONLNdN{{á⁄)cGfrom the implementation of the provisional node address for the purpose°dONLNdñáìT(Ø6Aof talking with the router to determine the valid network number °dONLNd◊áTì⁄(Ørrange to which the node is°dONLNdÚî†N(º6 connected. °dONLNd˝îN†L)63After obtaining the network range, .MPP issues the °dONLNd0ìLüå)˛    ADelNode °dONLNd9îå†⁄)@call to delete the°dONLNdL°≠ö(…6provisional node. The next °dONLNdg†ö¨Ÿ)Ç    ADelNode °dONLNdp°Ÿ≠)?call will be to °dONLNdİ≠⁄)B'acquire the unique node ID for the user°dONLNd®≠π*(’65node. As mentioned previously, .MPP can pass a value °dONLNd›≠*π⁄(’H"different from 0xFFFF for the user°dONLNdπ≈K(·6
  7962. node. The °dONLNd
  7963. πK≈⁄)3Ouser node is acquired before any multinode. The ADEV needs to keep track of the°dONLNdZΔ“P(Ó6
  7964. number of °dONLNdd≈P—à)8AAddNode°dONLNdlΔà“£)8 and °dONLNdq≈£—€)ADelNode°dONLNdyΔ€“µ)8, calls issued to determine whether the user °dONLNd•Δµ“⁄)⁄node is°dONLNd≠“fi°(˙6being acquired. Refer to °dONLNdΔ“°fi˜)âInside AppleTalk°dONLNd÷“˜fi,)V    , second °dONLNdfl“,fi⁄)5!edition, page 4-8, for additional°dONLNdfiÍS(6 information.°dONLNdˆg* AGetNodeRef°dONLNdˆgk)O °dONLNdˆkõ)(D0=11)°dONLNd"C(66
  7965. This is a °dONLNd,CZ)+new°dONLNd/Z)* call that is used by .MPP to find out if °dONLNdY⁄)∫)a multinode address exists on the current°dONLNdÉ&p(B6HADEV. This call is currently used by .MPP to check if a write should be °dONLNdÀp&⁄(Bélooped back to one of°dONLNd·&2"(N64the other nodes on the machine (the packet does not °dONLNd    &"2⁄(N@$actually need to be sent through the°dONLNd    :2>*(Z68network) or should be sent to the ADEV for transmission.°dONLNd    sJV.*Call:°dONLNd    zJ`Vy)HA0->°dONLNd    ÄJ®V$)HPointer to parameter block°dONLNd    õVb>(~6Return: °dONLNd    §V`by)HD0->°dONLNd    ™V®bà)H0= zero if address does not exist on this machine°dONLNd    flb®nb* (≠ zero if address exists on this machine°dONLNd
  7966. n®zè*
  7967. !atlkPBRec.AddrRefNum = AddrRefNum°dONLNd
  7968. -oè{í)Á °dONLNd
  7969. .oí{⁄)(corresponding°dONLNd
  7970. ={á$(£6to °dONLNd
  7971. D{®áÑ)ê0the node address) if the operation is successful ¡4¡˘
  7972. (÷656)
  7973.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ◊#ˇ ˇˇˇˇ#◊ 
  7974. IR,Times
  7975. .+Z-Developer Support Center(-Á January 1993 /X/,
  7976. Courier°dONLNdN)Ñ(El    atlkPBRec°dONLNd
  7977. ñ)∫)HRecord°dONLNd))ZcsParam°dONLNd(<4N(PZ-->°dONLNd(ñ4¿)ZNetAddr°dONLNd%(4)ZDS.L°dONLNd*(/45)?1°dONLNd,(<4‰)
  7978.  ; offset 0x1C  24-bit node °dONLNdN3<?¥*  ; address to remove°dONLNdc><JN(fZ<--°dONLNdg>ñJ“)Z
  7979. AddrRefNum°dONLNdr>J)ZDS.W°dONLNdw>/J5)?1°dONLNdy>AJ›); offset 0x2A  AddrRefNum °dONLNdôIAUÀ* ; passed in by AAddNode°dONLNd∂TA`É* ; on return°dONLNdƒ_ñkÆ(á¥EndR
  7980. °dONLNd…w<Éi(üZ
  7981. The field °dONLNd”viǰ)-NetAddr °dONLNd€w°És)8+is the 24-bit AppleTalk node address whose 
  7982. °dONLNdwsÉß)“
  7983. AddrRefNum
  7984. °dONLNdwßɲ)4 is requested. The°dONLNd#Ñ<ê(¨Z-node number is in the least significant byte °dONLNdPÑê )Ã0 of °dONLNdUÉ èQ)NetAddr°dONLNd\ÑQê˛)1". The network number is in bytes 1°dONLNdë<ù_(πZand 2 °dONLNdÖë_ùp)#of °dONLNdàêpú°)NetAddr°dONLNdèë°ù¥)12; byte 3 is unused. The address reference number, °dONLNd¡ê¥ú˙(π“
  7985. AddrRefNum°dONLNdÀë˙ù˛)F,°dONLNdÕû<™ò(ΔZassociated with the °dONLNd·ùò©…)\NetAddr°dONLNdËû…™.)1, must be returned to °dONLNd˛û.™˛)e&.MPP. Remember to return 0xFFFF as the°dONLNd%™<∂Ç(”Z
  7986. AddrRefNum
  7987. °dONLNd/´Ç∑Ö)F 
  7988. °dONLNd0´Ö∑Ÿ)for the user node.°dONLNdC√<œè(ÎZ AOpen (D0=7)°dONLNdP€<ÁR*Call:
  7989. °dONLNdYÁ`Ûr+$ -->°dONLNd]ÁÑÛú)$D4.B°dONLNdcÁÃÛ>)Hcurrent port number
  7990. °dONLNdwˇ< º('ZADEVs should expect the °dONLNdè˛º
  7991. fl)ÄAOpen°dONLNdîˇfl {)# call whenever the .MPP driver °dONLNd≥ˇ{ ˛)úis being opened. This is a°dONLNdŒ <Y(3Zgood °dONLNd” Y˛)Stime for the ADEV to register multicast addresses with the link layer or register a°dONLNd'<#](?Z=Transition Queue handler. After this call is completed, .MPP °dONLNdd]#˛(?{#is ready to receive packets. If the°dONLNdà$<09(LZ3ADEV does not process this message, simply return, °dONLNdª#9/N)˝RTN
  7992. °dONLNdæ$N0Q) 
  7993. °dONLNdø$Q0q)with a °dONLNdΔ#q/∑) 
  7994. ControlErr°dONLNd–$∑0ª)F.°dONLNd“=<Ij(eZ
  7995. Note that °dONLNd‹<jHç).AOpen°dONLNd·=çIa)#/ is not specific to the Multinode Architecture.°dONLNdU<aí(}Z
  7996. AClose (D0=8)°dONLNdm<yf*AClose°dONLNd%nfz)*# is called only when .MPP is being °dONLNdHnz˛)∞,closed (for example, .MPP is closed when the°dONLNduz<Üfi(¢Z%“inactive” option is selected in the °dONLNdözfiܲ)¢9Chooser or when the user switches links in network cdev).°dONLNd‘Ü<í,(ÆZ.The ADEV can use this event to deregister any °dONLNdÜ,í˛)*multicast addresses with the link layer or°dONLNd-ì<ü(ªZ-remove an existing Transition Queue handler. °dONLNdZìüG)⁄ After this °dONLNdeíGûq)1AClose°dONLNdkìqü˛)* call is completed, the ADEV°dONLNdàü<´»(«Zshould not defend for any °dONLNd¢ü»´˛)å7node addresses until .MPP reopens and acquires new node°dONLNd⁄´<∑u(”Z addresses. °dONLNd´u∑¿)9:If the ADEV does not process this message, simply return, 
  7997. °dONLNd´¿∑‹(”fiRTN 
  7998. °dONLNd#´‹∑˛)with a°dONLNd*∑<√Ç(‡Z
  7999. ControlErr°dONLNd4∏ǃÜ)F.°dONLNd6—<›j(˘Z
  8000. Note that °dONLNd@–j‹î).AClose°dONLNdF—î›h)*/ is not specific to the Multinode Architecture.°dONLNdvÍ<ˆ◊(Z For comparison, descriptions of °dONLNdñÈ◊ı)õAInstall°dONLNdû͈&)8 and °dONLNd£È&ıe)    AShutDown°dONLNd¨ÍeˆÈ)? are documented as follows:°dONLNd»<ñ(*ZAInstall (D0=1)°dONLNdÿ<&R*Call:
  8001. °dONLNdfl2N>`+-->°dONLNd„2r>ñ)$D1.L =°dONLNdÍ2®>‡)64value from PRAM (slot, ID, unused, atlk resource ID)°dONLNd =NI`(el<--°dONLNd$=rIñ)$D1.L =°dONLNd+=®IÊ)65high 3 bytes for parameter RAM returned by the ADEV, °dONLNddH®TÍ* if no error°dONLNdqSN_`({l<--°dONLNduSr_ñ)$D0.W =°dONLNd|S®_‰)6
  8002. error code
  8003. °dONLNdâk<wQ(ìZThe °dONLNdçjQvâ)AInstall°dONLNdïkâwΔ)8 call is made °dONLNd£kΔw˛)=>before .MPP is opened either during boot time or when the user°dONLNd‚w<ÉI(üZ9switches links in network cdev. This call is made during °dONLNdwIɲ(üg$system task time so that the ADEV is ¡X¡
  8004. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙57)
  8005.  of 61(ÏZM.NW.AppleTalk2ˇñ◊#ˇ ˇˇˇˇ#◊ 
  8006. IR,Times
  8007. .+6-Macintosh Technical Notes /4/˘
  8008. °dONLNd*v*Jallowed to allocate memory, make file system calls, or load resources and °dONLNdJv*∑(Fî
  8009. so on. Note: ,
  8010. Courier°dONLNdW∑)⁄)AAOpen°dONLNd]*6À(R6$call will be made during .MPP opens.°dONLNdÇBNâ*AShutDown (D0=2)°dONLNdì[gò*ADEVs should expect the °dONLNd´Zòf◊)Ä    AShutDown°dONLNd¥[◊g )?  call to be °dONLNd¿[ g⁄)4(made when the user switches links in the°dONLNdÈhtø(ê6Network cdev. The network cdev °dONLNdhøt_)ßcloses .MPP, which causes the °dONLNd&g_sâ)†AClose°dONLNd,hât⁄)* call to be made°dONLNd=uÅî(ù6before the cdev issues the °dONLNdXtîÄ”)|    AShutDown°dONLNdau”Å)? call. Note: the °dONLNdrtÄZ)H    AShutDown°dONLNd{uZŪ)? call is always made °dONLNdêuªÅ⁄)aduring°dONLNdóÅçª(©6Ysystem task time; therefore, deleting memory, unloading resources, and file system calls °dONLNdŪç⁄(©Ÿcan be°dONLNd˜çôi(µ6done at this time.°dONLNd
  8011. •±*Receiving Packets°dONLNdæ µ*The address reference number (°dONLNd:Ωµ…˚)ù
  8012. AddrRefNum°dONLNdDæ˚ ≤)F$) associated with each node address °dONLNdhæ≤ ⁄)∑must be°dONLNdp ÷(Ú6/passed to .MPP when delivering packets upward. °dONLNdü ÷⁄(Ú9 When making the LAP Manager call°dONLNd¿÷‚s(ˇ6
  8013. LReadDispatch°dONLNdÕ◊s„±)[C to deliver packets to AppleTalk, the ADEV must fill the high word °dONLNd◊±„ø(ˇœof °dONLNd÷ø‚Õ)D2°dONLNd◊Õ„⁄) in°dONLNd„ÔC( 6    with the °dONLNd"„CÔ⁄)+Paddress reference number, corresponding to the packet’s destination address (LAP°dONLNdsÔ˚2(6node °dONLNdxÔ2˚⁄)Uaddress in the LocalTalk case and DDP address in the non-LocalTalk case). There are a°dONLNdŒ˚l(#6few special cases:°dONLNd·ƒ*Z• In the case of broadcasts and packets directed to the user node, $FFFF (word) should be °dONLNd;ƒ⁄(;‚used°dONLNd@!+º(G? as the address reference number.°dONLNda7C÷(_6%• On non-LocalTalk networks, packets °dONLNdÜ7÷C⁄)æ3with DDP destination addresses matching neither the°dONLNd∫C!Oc(k?Buser node address nor any of the multinode addresses should still °dONLNd¸CcO⁄(kÅbe delivered to the LAP°dONLNdO![ü(w?QManager so that the router can forward the packet on to the appropriate network. °dONLNdeOü[⁄(wΩ
  8014. In this case,°dONLNds\!h{(Ñ?the high word of °dONLNdÑ[{gâ)ZD2°dONLNdÜ\âh) should be filled in with °dONLNd†\h⁄)'the address reference number, $FFFE, to°dONLNd»h!tH(ê?    indicate °dONLNd—hHt⁄)'Sto MPP that this packet is not for any of the nodes on the machine in the case of a°dONLNd%t!Ä(ú?3router running on a machine on an extended network.°dONLNdZåò2(¥6• On °dONLNd_å2ò⁄)QLocalTalk networks, the ADEV looks only at the LAP address; therefore, if the LAP°dONLNd±ò!§Δ(¿?"address is not the user node, one °dONLNd”òΔ§⁄)•7of the multinodes, or a broadcast, the packet should be°dONLNd §!∞c(Ã? thrown away.°dONLNdº»Õ(‰6Defending Multinode Addresses°dONLNd6‘‡@*6Both LocalTalk (RTS and CTS) and non-LocalTalk (AARP) °dONLNdl‘@‡⁄(¸^ADEVs have to be modified to°dONLNdâ‡ÏÆ(6Vdefend not only for the user node address but also for any active multinode addresses.
  8015. °dONLNd‡R*'-Corrections/Clarifications to the LAP Manager
  8016. °dONLNd+\*The interface °dONLNd\+⁄)DGfor the Link Access Protocol (LAP) Manager is presented in the document°dONLNdd+7"(S62Macintosh AppleTalk Connections Programmer’s Guide°dONLNdñ+"7o(S@, available from °dONLNdß+o7⁄)MAPDA, p/n M7056/A.°dONLNd∫7Cˇ(_61This section provides additional descriptions to °dONLNdÎ7ˇC⁄)Á*the LAP Manager functions described in the°dONLNd    COÄ(k6Programmer’s Guide.°dONLNd    *[gñ*LRdDispatch (D0 = 1)°dONLNd    ?sw*FThe LRdDispatch routine is called by an ADEV’s 'atlk' packet handling °dONLNd    Ösw⁄(õïroutine to notify the°dONLNd    õãö(ß6LAP Manager that a packet °dONLNd    µöã⁄)Ç@has been received, and to pass the packet to the LAP Manager for°dONLNd    ˆãó_(≥6Bprocessing by the appropriate protocol handler. The documentation °dONLNd
  8017. 8ã_ó⁄(≥}indicates that this routine ¡4¡˘
  8018. (÷658)
  8019.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇà◊#ˇ ˇˇˇˇ#◊ 
  8020. IR,Times
  8021. .+Z-Developer Support Center(-Á January 1993 /X/
  8022. °dONLNd<)Ä(EZE“even though it is called with a JSR, does not return to the caller, °dONLNdEÄ)˛(Eûbut jumps to the protocol°dONLNd_)<5o(QZEhandler that is attached to the protocol indicated in (register) D2.”°dONLNd¶A<MÖ*When called to °dONLNdµAÖM˛)IKhandle LRdDispatch, the LAP Manager searches its protocol table for a match°dONLNdM<Y9(uZ6to the protocol specified in D2. If found, the return °dONLNd7M9Y˛)˝&address placed on the stack by the JSR°dONLNd^Y<e§(ÅZQinstruction is removed. For this reason, the caller will not be returned to if a °dONLNdØY§e˛(Ŭprotocol handler is°dONLNd√e<q±(çZOfound. This also means that the packet handling routine that calls LRdDispatch °dONLNde±q˛(çœmust restore the°dONLNd#q<}ã(ôZHstack to the state the stack was in when the packet handler was entered.°dONLNdlâ<ïØ*LWrtInsert (D0 = 2)°dONLNdİ<≠F*;The LWrtInsert description indicates that setting bit 6 of °dONLNdª°F≠˛(…d'the flag byte in register D1, “does not°dONLNd„≠<πè(’ZBdisable the port B serial communications controller (SCC).…” This °dONLNd%≠èπ˛(’≠bit no longer has any°dONLNd;π<≈∫(·Zmeaning under AppleTalk.
  8023. °dONLNdU›<Ï*'AppleTalk Version Information
  8024. °dONLNds¯<Ù*$The following table is presented to °dONLNdó¯Ù˛)∏2assist AppleTalk developers in understanding which°dONLNd <(,Z*versions of AppleTalk are required by the °dONLNdÙ˛)’.various AppleTalk products. This list does not°dONLNd#<ù(8ZLidentify the individual bug fixes associated with each release of AppleTalk.,
  8025. Courier
  8026.     °dONLNdp5C@y+$    AppleTalk°dONLNdz?CJm*
  8027. Version°dONLNdÇ5ã@£(\©.MPP°dONLNdá?ãJµ*
  8028. Version°dONLNdè5”@Î(\Ò.ATP°dONLNdî?”J˝*
  8029. Version°dONLNdù?J·)H!Apple Products Using That Version"S\#"S]F"S§"S•F"SÏ"SÌF"S4 S5S "S!#"T\"T§"TÏ"T4"T!"h\"h]F"h§"h•F"hÏ"hÌF"h4 h5h "h!"i\    "i§    "iÏ    "i4    "i!    °dONLNd≈TC_M({a19°dONLNd»Tã_ï)H19°dONLNdÀT”_›)H19°dONLNdŒT_u)HMacintosh Plus ROM"s\    "s§    "sÏ    "s4    "s!    °dONLNd‚^CiM(Öa48°dONLNdÂ^ãiï)H48°dONLNdË^”i›)H46°dONLNdÎ^ik)HMacintosh SE ROM"}\    "}§    "}Ï    "}4    "}!    °dONLNdhsÑ*
  8030. Macintosh Classic ROM"á\    "á§    "áÏ    "á4    "á!    °dONLNdrC}W(ôa48.1°dONLNdrã}ï)H48°dONLNdr”}›)H46°dONLNd"r}¢)HAppleShare File Server v1.0"ë\    "ë§    "ëÏ    "ë4    "ë!    °dONLNd?|CáM(£a49°dONLNdB|ãáï)H49°dONLNdE|”á›)H49°dONLNdH|ák)HMacintosh II ROM"õ\    "õ§    "õÏ    "õ4    "õ!    °dONLNd]Üëu*
  8031. Macintosh IIcx ROM"•\    "•§    "•Ï    "•4    "•!    °dONLNdtêõf*
  8032. Macintosh SE/30"Ø\    "ا    "ØÏ    "Ø4    "Ø!    °dONLNdÖöC•M(¡a50°dONLNdàöã•ï)H50°dONLNdãö”•›)H49°dONLNdéö•¢)HAppleShare File Server v1.1"π\    "π§    "πÏ    "π4    "π!    °dONLNd´§CØM(Àa51°dONLNdƧãØï)H51°dONLNd±§”Ø›)H51°dONLNd¥§Øß)HAppleShare Print Server v2.0"√\    "√§    "√Ï    "√4    "√!    °dONLNd“ÆCπM(’a52°dONLNd’Æãπï)H52°dONLNdÿÆ”π›)H52°dONLNd€Æπ¢)HAppleShare File Server v2.0"Õ\    "Õ§    "ÕÏ    "Õ4    "Õ!    °dONLNd˚∏√p*
  8033. Macintosh IIx ROM"◊\    "◊§    "◊Ï    "◊4    "◊!    °dONLNd¬Õu*
  8034. Macintosh IIci ROM"·\    "·§    "·Ï    "·4    "·!    °dONLNd(Ã◊â*
  8035. Macintosh Portable ROM"Î\    "Χ    "ÎÏ    "Î4    "Î!    °dONLNdC÷·p*
  8036. PowerBook 100 ROM"ı\    "ı§    "ıÏ    "ı4    "ı!    "ˇ\    "    \#"    ]F"ˇ§    "    §"    •F"ˇÏ    "    Ï"    ÌF"ˇ4    "    4     5     "ˇ!    "    !#
  8037. °dONLNd\˜ÒI(Phase 1 drivers ¡X¡
  8038. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙59)
  8039.  of 61(ÏZM.NW.AppleTalk2ˇæ◊#ˇ ˇˇˇˇ#◊ 
  8040. IR,Times
  8041. .+6-Macintosh Technical Notes /4/˘,
  8042. Courier
  8043.     °dONLNd*5U+$    AppleTalk°dONLNd
  8044. 4?I*
  8045. Version°dONLNd*g5(QÖ.MPP°dONLNd4g?ë*
  8046. Version°dONLNd*Ø5«(QÕ.ATP°dONLNd$4Ø?Ÿ*
  8047. Version°dONLNd-4˜?Ω)H!Apple Products Using That Version"H8#"H9F"HÄ"HÅF"H»"H…F"H HH¸"H˝#"I8"]8#"]9F"IÄ"]Ä"]ÅF"I»"]»"]…F"I"] ]]¸"I˝"]˝#°dONLNdP>I)(e=53°dONLNdS>gIq)H53°dONLNdV>ØIπ)H53°dONLNdY>˜Iy)HAppleTalk Phase 2 products"]8    "]Ä    "]»    "]    "]˝    °dONLNdxI˜Tç* AppleTalk Internet Router v2.0"h8    "hÄ    "h»    "h    "h˝    °dONLNdõS˜^~*
  8048. Apple EtherTalk NB Card 2.0"r8    "rÄ    "r»    "r    "r˝    °dONLNdª]˜h~*
  8049. Apple TokenTalk NB Card 2.0"|8    "|Ä    "|»    "|    "|˝    °dONLNdÿgr)(é=54°dONLNd€ggrq)H54°dONLNdfigØrπ)H54°dONLNd·g˜r=)HMacintosh IIfx"Ü8    "ÜÄ    "Ü»    "Ü    "Ü˝    °dONLNdÙq˜|~*
  8050. Macintosh LC, LC II, & IIsi"ê8    "êÄ    "ê»    "ê    "ê˝    °dONLNd{Ü)(¢=55°dONLNd{gÜq)H55°dONLNd{ØÜπ)H55°dONLNd{˜Üƒ)H)Apple Ethernet LC Card (for Macintosh LC)"ö8    "öÄ    "ö»    "ö    "ö˝    °dONLNdEÖê)(¨=56°dONLNdHÖgêq)H56°dONLNdKÖØêπ)H56°dONLNdNÖ˜êL)HSystem 7.0, 7.0.1"§8    "§Ä    "§»    "§    "§˝    °dONLNddè˜ö[*
  8051. Macintosh Classic II"Æ8    "ÆÄ    "Æ»    "Æ    "Æ˝    °dONLNd}ô˜§É*
  8052. PowerBook 140, 160, 170, 180"∏8    "∏Ä    "∏»    "∏    "∏˝    °dONLNdû£˜Æç*
  8053. Macintosh Quadra 700, 900, 950"¬8    "¬Ä    "¬»    "¬    "¬˝    °dONLNdæ≠∏=(‘=57.0.1°dONLNd≈≠g∏Ö)H57.0.1°dONLNdÃ≠Ø∏Õ)H57.0.1°dONLNd”≠˜∏j)HAppleTalk Remote Access"Ã8    "ÃÄ    "û    "à   "Ã˝    °dONLNdÔ∑˜¬É*
  8054. Apple TokenRing 4/16 NB Card"÷8    "÷Ä    "÷»    "÷    "÷˝    °dONLNd¡˜Ãe*
  8055. Apple Ethernet NB Card"‡8    "‡Ä    "‡»    "‡    "‡˝    °dONLNd(À÷=(Ú=57.0.3°dONLNd/Àg÷Ö)H57.0.3°dONLNd6ÀØ÷Õ)H57.0.3°dONLNd=À˜÷”)H,Apple Ethernet LC Card (for Macintosh LC II)"Í8    "ÍÄ    "Í»    "Í    "Í˝    °dONLNdk’‡=(¸=57.0.4°dONLNdr’g‡Ö)H57.0.4°dONLNdy’؇Õ)H57.0.4°dONLNdÄ’˜‡ó)H MacTCP Token Ring Extension v1.0"Ù8    "ÙÄ    "Ù»    "Ù    "Ù˝    °dONLNd•fl˜Ío*
  8056. System 7.1, MacTCP 1.1.1"˛8    "˛Ä    "˛»    "˛    "˛˝    °dONLNd¬Í˜ıe* Macintosh Duo 210, 230"8    ™U™U™U™U"9F    ˇˇˇˇˇˇˇˇ"Ä    ™U™U™U™U"ÅF    ˇˇˇˇˇˇˇˇ"»    ™U™U™U™U"…F    ˇˇˇˇˇˇˇˇ"    ™U™U™U™U ¸    ˇˇˇˇˇˇˇˇ"˝"    8    "    Ä    "    »    "        "    ˝    °dONLNd›ı˜[* Macintosh IIvi, IIvx"8    ™U™U™U™U"9F    ˇˇˇˇˇˇˇˇ"Ä    ™U™U™U™U"ÅF    ˇˇˇˇˇˇˇˇ"»    ™U™U™U™U"…F    ˇˇˇˇˇˇˇˇ"    ™U™U™U™U ¸    ˇˇˇˇˇˇˇˇ"˝"8    "Ä    "»    "    "˝    °dONLNdˆ˜ j* Macintosh Color Classic"8    ™U™U™U™U"9F    ˇˇˇˇˇˇˇˇ"Ä    ™U™U™U™U"ÅF    ˇˇˇˇˇˇˇˇ"»    ™U™U™U™U"…F    ˇˇˇˇˇˇˇˇ"    ™U™U™U™U ¸    ˇˇˇˇˇˇˇˇ"˝"8    "Ä    "»    "    "˝    °dONLNd ˜B* Macintosh LC II")8    ™U™U™U™U")9F    ˇˇˇˇˇˇˇˇ")Ä    ™U™U™U™U")ÅF    ˇˇˇˇˇˇˇˇ")»    ™U™U™U™U")…F    ˇˇˇˇˇˇˇˇ")    ™U™U™U™U ))¸    ˇˇˇˇˇˇˇˇ")˝"*8    "*Ä    "*»    "*    "*˝    °dONLNd&˜!=* PowerBook 165c"48    ™U™U™U™U"49F    ˇˇˇˇˇˇˇˇ"4Ä    ™U™U™U™U"4ÅF    ˇˇˇˇˇˇˇˇ"4»    ™U™U™U™U"4…F    ˇˇˇˇˇˇˇˇ"4    ™U™U™U™U 44¸    ˇˇˇˇˇˇˇˇ"4˝"58    "5Ä    "5»    "5    "5˝    °dONLNd9!˜,[* Macintosh Quadra 800"?8    ™U™U™U™U"?9F    ˇˇˇˇˇˇˇˇ"?Ä    ™U™U™U™U"?ÅF    ˇˇˇˇˇˇˇˇ"?»    ™U™U™U™U"?…F    ˇˇˇˇˇˇˇˇ"?    ™U™U™U™U ??¸    ˇˇˇˇˇˇˇˇ"?˝"@8    "@Ä    "@»    "@    "@˝    °dONLNdR,˜7y* Macintosh Centris 610, 650"J8    ™U™U™U™U"J9F    ˇˇˇˇˇˇˇˇ"JÄ    ™U™U™U™U"JÅF    ˇˇˇˇˇˇˇˇ"J»    ™U™U™U™U"J…F    ˇˇˇˇˇˇˇˇ"J    ™U™U™U™U JJ¸    ˇˇˇˇˇˇˇˇ"J˝"K8    "KÄ    "K»    "K    "K˝    °dONLNdn7B)(^=58°dONLNdq7gBq)H58°dONLNdt7ØBπ)H58°dONLNdw7˜By)HApple Internet Router v3.0"U8    ™U™U™U™U"U9F    ˇˇˇˇˇˇˇˇ"UÄ    ™U™U™U™U"UÅF    ˇˇˇˇˇˇˇˇ"U»    ™U™U™U™U"U…F    ˇˇˇˇˇˇˇˇ"U    ™U™U™U™U UU¸    ˇˇˇˇˇˇˇˇ"U˝"V8    "VÄ    "V»    "V    "V˝    °dONLNdñB˜M* Mac SNMP"`8    ™U™U™U™U"`9F    ˇˇˇˇˇˇˇˇ"`Ä    ™U™U™U™U"`ÅF    ˇˇˇˇˇˇˇˇ"`»    ™U™U™U™U"`…F    ˇˇˇˇˇˇˇˇ"`    ™U™U™U™U ``¸    ˇˇˇˇˇˇˇˇ"`˝"a8    "k8#"k9F"aÄ    "kÄ"kÅF"a»    "k»"k…F"a    "k kk¸"a˝    "k˝#
  8057. °dONLNd°YÕe%(ÅÎPhase 2 drivers°dONLNd±q}Ü(ô6Some interesting notes:°dONLNd…â*ï1+• °dONLNdÃâ7ï*)
  8058. -.MPP and .ATP driver versions weren’t always °dONLNd˘â*ï⁄)Û!the same in versions of AppleTalk°dONLNdï7°®(ΩUKbefore version 51. The .MPP driver version is the AppleTalk version number.°dONLNdg≠*π1(’H• °dONLNdj≠7πm)
  8059. The Phase °dONLNdt≠mπ⁄)6G1 RAM-based drivers (versions 49 through 52) were supplied as file that°dONLNdºπ7≈≈(·Ucould be drag-installed (that °dONLNd⁄π≈≈⁄)é8is, the installation consisted of dropping them into the°dONLNd≈7—Ñ(ÌUSystem Folder).°dONLNd#›*È1(H• °dONLNd&›7È)
  8060. (The Phase 2 RAM-based drivers (versions °dONLNdN›È⁄)ÿ&53 through 58) must be installed by an°dONLNduÈ7ı (U#Installer script that will install °dONLNdòÈ ı⁄)ì7the various system pieces (files, resources, and so on)°dONLNd–ı7Ã(UVneeded to load and support these new drivers; these versions cannot be drag-installed.°dONLNd'
  8061. *1(5H• °dONLNd*
  8062. 7G)
  8063. 9AppleTalk version 56 or greater includes the .DSP driver °dONLNdc
  8064. G⁄(5e(ADSP). Starting with version°dONLNdÅ7%m(AUA56, the .DSP driver version is the same as the AppleTalk version.°dONLNd√1=î(Y6KApple software products that require the Phase 2 RAM-based drivers must be °dONLNd1î=⁄(Y≤installed using°dONLNd=Iw(e6Ithe Installer program. Apple supplies an Installer script that will copy °dONLNdg=wI⁄(eïall files and system°dONLNd|IUô(q6Tresources needed. Apple licenses the source to an Installer script that you can use °dONLNd–IôU⁄(q∑if you license°dONLNdflUaÕ(}6%AppleTalk to ship with your products. ¡4¡˘
  8065. *Y60)
  8066.  of 61(÷K(NW 13 - AppleTalk: The Rest of the Story+_M.NW.AppleTalk2ˇ    R◊#ˇ ˇˇˇˇ#◊ 
  8067. IR,Times
  8068. .+Z-Developer Support Center(-Á January 1993 /X/
  8069. °dONLNd<,4(HZ#Contacting Apple Software Licensing
  8070. °dONLNd$8<D*-Software Licensing can be reached as follows:°dONLNdSP`\º+$Software Licensing°dONLNdg\`h»* Apple Computer, Inc.°dONLNd}h`t˛* 20525 Mariani Avenue, M/S 38-I°dONLNdùt`Ä«* Cupertino, CA 95014°dONLNd≤Ä`å™*
  8071. MCI: 312-5360°dONLNd¡å`òfl* AppleLink: SW.LICENSE°dONLNdÿò`§F* (Internet: SW.LICENSE@AppleLink.Apple.com°dONLNd§`∞®*
  8072. (408)974-4667°dONLNd‘<‡¶(¸ZFurther Reference: ˇXˇ°dONLNd#·NÌR+
  8073. •°dONLNd%·`̵)Inside AppleTalk,°dONLNd6·µÌV)U Second Edition, Addison-Wesley°dONLNdVÌN˘R(l•°dONLNdXÌ`˘±)Inside Macintosh°dONLNdẖ˘Ô)Q
  8074. , Volume II, °dONLNduÌÔ˘a)>The AppleTalk Manager°dONLNdäÌa˘∑)r, Addison-Wesley°dONLNdõ˘NR(!l•°dONLNdù˘`±)Inside Macintosh°dONLNd≠˘±Ô)Q , Volume V, °dONLNdπ˘Ôa)>The AppleTalk Manager°dONLNdŒ˘a∑)r, Addison-Wesley°dONLNdflNR(-l•°dONLNd·`±)Inside Macintosh°dONLNdÒ±Û)Q
  8075. , Volume VI, °dONLNd˛Ûe)BThe AppleTalk Manager°dONLNdeª)r, Addison-Wesley°dONLNd$NR(9l•°dONLNd&`“)Macintosh AppleTalk °dONLNd:“Ä)rConnections Programmer’s Guide°dONLNdXIJ)Æ, Final Draft 2, Apple°dONLNdo`)·(E~Computer, Inc. (M7056/A)°dONLNdà)N5R(Ql•°dONLNdä)`5$)(AppleTalk Phase 2 Protocol Specification°dONLNd≤)$5◊)ƒ", Apple Computer, Inc. (C0144LL/A)°dONLNd’5NAR(]l•°dONLNd◊5`AD)-AppleTalk Remote Access Developer’s Toolkit, °dONLNd5DA)‰ Apple Computer, Inc. (R0128LL/A)°dONLNd%ANMR(il•°dONLNd'A`M—)M.NW.AppleTalk2Mac°dONLNd:e<q(çZ*NuBus is a trademark of Texas Instruments. ¡X¡
  8076. (÷Z(NW 13 - AppleTalk: The Rest of the Story(÷˙61)
  8077.  of 61(ÏZM.NW.AppleTalk2ˇ¬◊#ˇ ˇˇˇˇ#◊†Ç 
  8078. /ZÅ#
  8079.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  8080. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  8081. .R…R…+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  8082. ({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  8083. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  8084.     +&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  8085. (Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É
  8086. IR.°dONLNdn<Åv(õZ"NW 14 - AppleTalk Timers Explained
  8087. °dONLNd#Ä<èä*
  8088. Networking
  8089. °dONLNd/õ<ßq* Written by:°dONLNd;õÑß*)HSriram Subramanian & Pete Helme°dONLNd[õÀ߲(√È
  8090. April 1990°dONLNdf≥<ø€(€ZWThis Technical Note explains how to effectively use timers and retry mechanisms of the °dONLNdΩ≥€ø˛(€˘various°dONLNd≈ø<ÀÖ(ÁZBAppleTalk protocols to achieve maximum performance on an internet. ˆXˆ°dONLNd‰<‚*% The most fundamental service in °dONLNd(‰‚˛)¶7an AppleTalk internet is the Datagram Delivery Protocol°dONLNd`<¸Ù(ZY(DDP), which provides a best-effort, connectionless, packet delivery system.  A sequence °dONLNdπÙ¸˛(of°dONLNdº¸<∂($ZKpackets sent using DDP on an AppleTalk internet between a pair of machines °dONLNd¸∂˛($‘may traverse a°dONLNd<O(0Z9single high-speed Ethernet network or it may wind across °dONLNdOO˛(0m%multiple intermediate data links such°dONLNdu< I(<Zas °dONLNdxI ˛)
  8091. WLocalTalk, TokenRing, etc., which are connected by routers.  Some packet loss is always°dONLNd– <,,(HZ4inevitable because of the loosely coupled nature of °dONLNd ,,˛)*the underlying networks.  Even on a single°dONLNd/,<8(TZ,high-speed Ethernet network, packets can be °dONLNd[,8˛)÷2lost due to collisions or a busy destination node.°dONLNdè8<D (`Z.The AppleTalk Transaction Protocol (ATP), the °dONLNdΩ8 D˛)‰*AppleTalk Data Stream Protocol (ADSP), and°dONLNdËD<P&(lZ2other high-level protocols protect against packet °dONLNdD&P˛)Í-loss and ensure reliability by using positive°dONLNdHP<\Q(xZ6acknowledgement with  packet retransmission mechanism.°dONLNdh<t˙*%The basic transaction process in ATP °dONLNd§h˙t˛)æ3consists of a client in a requesting node sending a°dONLNdÿt<Ć(úZDTransaction Request (TReq) packet to a client in a responding node. °dONLNdt†Ä˛(úæ The client in the°dONLNd/Ä<åZ(®Z7responding node is expected to service the request and °dONLNdfÄZå˛(®x generate a series of Transaction°dONLNdáå<òÃ(¥ZLResponse (TResp) packets, which also serves as an acknowledgement.  The ATP °dONLNd”åÃò˛(¥Í
  8092. process in°dONLNdfiò<§~(¿ZCthe requesting node also starts a timer when it sends a packet and °dONLNd!ò~§˛(¿úretransmits a packet if the°dONLNd=§<∞6(ÃZ6timer expires before a complete response arrives.  In °dONLNds§6∞˛)˙+a large internet with multiple gateways, it°dONLNdü∞<ºx(ÿZ>is impossible to know how quickly acknowledgements may return °dONLNd›∞xº˛(ÿñto the requestor.  If you set°dONLNd˚º<»fi(‰Z$the retry time to be too small, you °dONLNdºfi»˛)¢;may be retransmitting a request while a delayed response is°dONLNd[»<‘b(Zen route°dONLNdc»b‘±)&, but if you wait °dONLNdu»±‘˛)OEtoo long to retransmit a request, application performance may suffer.°dONLNdº‘<‡ï(¸ZMore importantly, °dONLNdŒ‘ï‡˛)YKthe delay at each gateway depends upon the traffic, so the time required to°dONLNd‡<ÏÎ(ZUtransmit a packet and receive an acknowledgement varies from one instant to another. °dONLNdo‡ÎÏ˛(     To°dONLNdsÏ<¯µ(ZPfurther complicate matters, two packets sent back to back could take completely °dONLNd√ϵ¯˛(”different routes°dONLNd‘¯<ê( Zto the destination.
  8093. °dONLNdË<+b*'(Selecting ATP Retry Time And Retry Count
  8094. °dONLNd    7<Co*AYou can use the round trip time for a transaction as a heuristic °dONLNd    R7oC˛(_çfor setting the retry time and°dONLNd    qC<O◊(kZ"retry count.  The round trip time °dONLNd    ìC◊O˛)õ?between two nodes in a particular internet at a particular time°dONLNd    ”O<[¨(wZis usually deterministic.°dONLNd    Ìg<sª*UThe easiest way to set the retry time is to assign a static value based on the round °dONLNd
  8095. Bgªs˛(èŸtrip time for a°dONLNd
  8096. Rs<†(õZJtransaction.  The AppleTalk Echo Protocol (AEP) can be used to obtain the °dONLNd
  8097. ús†˛(õæround trip time in a°dONLNd
  8098. ±<ãn(ßZ<given moment between two nodes.  AEP is implemented in each °dONLNd
  8099. Ìnã˛(ßånode as a DDP client residing°dONLNd ã<óŸ(≥ZTon statically-assigned socket number four.  You should use DDP to send AEP requests °dONLNd _ãŸó˛(≥˜through ¡X¡
  8100. (÷Z"NW 14 - AppleTalk Timers Explained(÷1) of 5(ÏZM.NW.AppleTalkTimerˇ°¿Ù%%DSIDICT:_cv
  8101. currentdict /bu known {bu}if
  8102. userdict /_cv known not{userdict /_cv 30 dict put}if
  8103. _cv begin
  8104. /bdf{bind def}bind def
  8105. currentscreen/cs exch def/ca exch def/cf exch def
  8106. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  8107. /ss{//cf //ca //cs setscreen}bdf
  8108. /stg{ss setgray}bdf
  8109. /strgb{ss setrgbcolor}bdf
  8110. /stcmyk{ss cvcmyk}bdf
  8111. /min1{dup 0 eq{pop 1}if}bdf
  8112. end
  8113. currentdict /bn known {bn}if
  8114. †øp◊#ˇ ˇˇˇˇ#◊ 
  8115. IR,Times
  8116. .+6-Macintosh Technical Notes /4/˘
  8117. °dONLNd)∂*"any socket that is available, and °dONLNd"∂)⁄)û7you should use the maximum packet size that you plan on°dONLNdZ)5¥(Q6Vusing in your application.  You can listen for AEP responses by implementing a socket °dONLNd∞)¥5⁄(Q“    listener.°dONLNdª5A(]65The following code is an example AEP socket listener.,
  8118. Courier
  8119.     °dONLNdÒMXä*J;_________________________________________________________________________°dONLNd<Wbä*
  8120. J;_________________________________________________________________________°dONLNdáal*
  8121. ;°dONLNdâkvJ*
  8122.  
  8123. ; EchoDude°dONLNdîuÄ*
  8124. ;°dONLNdñäw*
  8125. ; 3/90 pvh - MacDTS°dONLNd™âî*
  8126. ;°dONLNd¨ìû¶*
  8127. ; ©1990 Apple Computer, Inc.°dONLNd…ù®*
  8128. ;°dONLNdÃß≤û*
  8129. N; The following MPW Asm code is a socket listener for reading in returned Echo°dONLNd±ºã*
  8130. ; (DDP type 4) packets.°dONLNd6ªΔ*
  8131. ;°dONLNd8≈–≠*
  8132. Q; The target device was shipped a packet with a '1' in the first byte of the data°dONLNdãœ⁄≠*
  8133. Q; area by way of a DDPWrite.  It was sent to socket 4, the Echoer socket.  If the°dONLNd›Ÿ‰£*
  8134. O; target device has an Echoer, it will send a return packet to us of equal size°dONLNd.„Ó≤*
  8135. R; except it will have replaced the '1' in the first byte with the value '2'.  This°dONLNdÇ̯∏*
  8136.  ; indicates an EchoReply packet.°dONLNd£˜*
  8137. ;°dONLNd• ∑*
  8138. S; The listener itself (RcvEcho) is added with a POpenSkt (Inside Mac V-513) call by°dONLNd˙ ∑*
  8139. S; passing the address of the listener in the listener field of the parameter block.°dONLNdN *
  8140. ;°dONLNdP*ô*
  8141. M; All we really are trying to accomplish here is to set up a notification for°dONLNdü)4î*
  8142. L; returned packets from the target Echoer.  A time (Ticks) is stuffed into a°dONLNdÏ3>∑*
  8143. S; location our app can find (actually back into the packet buffer) and will be used°dONLNdA=Hº*
  8144. T; to calculate round trips times.  We'll also save off the hop count from the packet°dONLNdñGR®*
  8145. P; header for fun too since I have nothing better to do with my time on weekends.°dONLNdÁQ\*
  8146. ;°dONLNdÈ[fû*
  8147. N; More could be done with this listener as far as making sure that we are only°dONLNd9epä*
  8148. J; receiving back a packet from the node we sent it to etc.... but we can't°dONLNdÖozû*
  8149. N; encompass everything in a sample.  Okay, well we could… but we have to leave°dONLNd’yÑ≥*
  8150. ; something for you guys to do.°dONLNdıÉé*
  8151. ;°dONLNd˜çòè*
  8152. K; It should be noted that careful preservation of register A5 is necessary.°dONLNdDó¢Ä*
  8153. H; LAP requires that A5 be preserved AFTER the call to ReadRest. i.e. you°dONLNdç°¨∑*
  8154. S; cannot save A5 onto the stack when your socket listener is entered, call ReadRest°dONLNd·´∂∑*
  8155. S; and then restore A5 from the stack and exit.  Wah.  LAP requires that the address°dONLNd5µ¿î*
  8156. L; placed in A5 during ReadRest be there when your socket listener is exited.°dONLNdÇø ≠*
  8157. Q; So… if you need a different A5 after the call to ReadRest make sure you restore°dONLNd’…‘Ã*
  8158. $; it before RTS-ing back the caller.°dONLNd˙”fi*
  8159. ;°dONLNd¸›Ë*
  8160. ;°dONLNd˛ÁÚT*
  8161. ;    Called:°dONLNd     Ò¸*
  8162. 2;         A0,A1,D1 : Preserve until after ReadRest°dONLNd    >˚«*
  8163. #;         A2 -> MPP local variables°dONLNd    bÃ*
  8164. $;         A3 -> RHA after DDP header°dONLNd    á˘*
  8165. -;         A4 -> ReadPacket, 2(A4) -> ReadRest°dONLNd    µ$«*
  8166. #;         A5 Useable until ReadRest°dONLNd    Ÿ#.Â*
  8167. );         A6,D4-D7 : Preserve across call°dONLNd
  8168. -8*
  8169. ;°dONLNd
  8170. 7Bè*
  8171. K;__________________________________________________________________________°dONLNd
  8172. QKV*/EchoSkt    EQU    4        ; Echo socket number°dONLNd
  8173. ÅU`
  8174. *
  8175. 1EP         EQU    4        ; EP DDP protocol type°dONLNd
  8176. ≥_j*
  8177. 2EPReq      EQU    1        ; Code for echo request°dONLNd
  8178. Êit*
  8179. 0EPReply    EQU    2        ; Code for echo reply°dONLNd }à*;°dONLNd áí÷*
  8180. &; Read the packet into the echo buffer ¡4¡˘
  8181. *(2) of 5(÷_"NW 14 - AppleTalk Timers Explained+8M.NW.AppleTalkTimerˇÙ◊#ˇ ˇˇˇˇ#◊ 
  8182. IR,Times
  8183. .+Z-Developer Technical Support(-
  8184. April 1990 /X/,
  8185. Courier
  8186.     °dONLNd<(A(DZ;°dONLNd1<<π*RcvEcho    PROC    EXPORT°dONLNd;<F*
  8187. *                   EXPORT    our_A5 : CODE°dONLNdGE<P*
  8188. ,                   EXPORT    our_Buff : CODE°dONLNdtO<Z˙*
  8189. &                   IMPORT    GBOB:DATA°dONLNdõc<n√*        BRA.S     checkEcho°dONLNd∑m<xZ*
  8190. our_A5°dONLNdæw<Çõ*
  8191.         DC.L      0°dONLNd“Å<åd*
  8192. our_Buff°dONLNd€ã<ñõ*
  8193.         DC.L      0°dONLNdÔï<†d*
  8194. our_Hops°dONLNd¯ü<™õ*
  8195.         DC.W      0°dONLNd ©<¥i*
  8196.     our_Ticks°dONLNd≥<æõ*
  8197.         DC.L      0°dONLNd*Ω<»i*
  8198.     checkEcho°dONLNd4«<“ö*
  8199. F        CMP.B     #EP,-(A3)            ; Make sure it's an echo packet°dONLNd{—<‹Y*
  8200. 9        BNE.S     RcvEIgnore           ; Ignore it if not°dONLNdµ€<Ê;*
  8201. 3        LEA       toRHA(A2), A3        ; top of RHA°dONLNdÈÂ<@*
  8202. 4        CLR.L     D2                   ; clean up D2°dONLNdÔ<˙1*
  8203. 1        MOVE.B    lapType(A3), D2      ; lap type°dONLNdP˘<«*
  8204. O        CMP.B     #longDDP, D2         ; check for long header (Type #2 packet)°dONLNd†<ü*
  8205. G        BNE.S     noHops               ; wah... no hops if short packet°dONLNdË
  8206. <‡*
  8207. T        MOVE.B    lapType+1(A3), D2    ; this is the hop count byte, 1st byte in DDP°dONLNdB"'+¥
  8208.    ; header°dONLNdN!<,‡(HZT        AND.B     #$3C, D2             ; mask to middle 4 bits of byte for hop count°dONLNd£+<6¬*
  8209. N                                       ;     | x | x | H | O | P | S | x | x |°dONLNdÚ5<@r*
  8210. >        ASR.B     #2, D2               ; shift 2 bits to right°dONLNd1?<Jw*
  8211. ?        LEA       our_Hops, A3         ; address of our storage°dONLNdqI<T§*
  8212. H        MOVE.B    D2, (A3)             ; move # of hops into our storage°dONLNd∫S<^Z*
  8213. noHops°dONLNd¡]<hÆ*
  8214. J        MOVE.W    #DDPMaxData, D3      ; our buffer is #DDPMaxData in size°dONLNd g<r¬*
  8215. N        LEA       our_Buff, A3         ; address of buffer to read packet into°dONLNd[q<|;*
  8216. 3        MOVE.L    (A3), A3             ; set buffer°dONLNdè{<Üü*
  8217. G        JSR       2(A4)                ; ReadRest of packet into buffer°dONLNd◊Ö<êr*
  8218. >        BEQ.S     RcvEchoReply         ; If no error, continue°dONLNdè<ö"*
  8219. .        BRA.S     RcvEchoFail          ; dang…°dONLNdEô<§n*
  8220.  
  8221. RcvEIgnore°dONLNdP£<Æm*
  8222. =        CLR       D3                   ; Set to ignore packet°dONLNdé≠<∏ü*
  8223. G        JMP       2(A4)                ; Ignore it, ReadRest and return°dONLNd÷∑<¬Õ*
  8224.         BRA.S     RcvEchoFail°dONLNdÙ¡<Ãx*
  8225. RcvEchoReply°dONLNdÀ<÷Ã*
  8226. P        CMP.B     #EPReply, -DDPMaxData(A3)    ; make sure it's our reply packet°dONLNdR’<‡—*
  8227. Q                                       ; it shouldn't be anything else, but check°dONLNd§fl<ÍE*
  8228. 5                                       ; just in case°dONLNd⁄È<Ùã*
  8229. C        BNE.S     RcvEchoFail          ; if not our reply then blow°dONLNdÛ<˛T*
  8230. 8        MOVE.L    A5, D2               ; save dude in D2°dONLNdW˝<§*
  8231. H        LEA       our_A5, A5           ; address of our A5 local storage°dONLNd†<÷*
  8232. R        MOVE.L    (A5), A5             ; make A5 our A5 for application global use°dONLNdÛ<©*
  8233. I        MOVE.B    #1, GBOB(A5)         ; set flag confirming reception of°dONLNd    =<&^*
  8234. :                                       ; echo reply packet°dONLNd    x%<0‡*
  8235. T        LEA       our_Buff, A3         ; address of our local buffer storage into A3°dONLNd    Õ/<:Æ*
  8236. J        MOVE.L    (A3), A3             ; get saved pointer and set buffer.°dONLNd
  8237. 9<D—*
  8238. Q        LEA       our_Hops, A5         ; address of hops local storage… notice we°dONLNd
  8239. jC<Nü*
  8240. G                                       ; are TRASHING A5 with this!!!!!°dONLNd
  8241. ≤M<Xê*
  8242. D        MOVE.W    (A5), (A3)+          ; copy in hop count to buffer°dONLNd
  8243. ˜W<bc*
  8244. ;        MOVE.L    Ticks, (A3)          ; next copy in Ticks°dONLNd 3k<vE*5        MOVE.L    D2, A5               ; restore dude°dONLNd iu<ÄY*
  8245. 9        RTS                            ; return to caller°dONLNd £<äs*
  8246. RcvEchoFail°dONLNd Øâ<îY*
  8247. 9        RTS                            ; return to caller ¡X¡
  8248. *&"NW 14 - AppleTalk Timers Explained(÷3) of 5(ÏZM.NW.AppleTalkTimerˇ◊#ˇ ˇˇˇˇ#◊ 
  8249. IR,Times
  8250. .+6-Macintosh Technical Notes /4/˘,
  8251. Courier
  8252.     °dONLNd'2T*!         ENDP°dONLNd
  8253. ;F¬*"setUpSktListener    PROC    EXPORT°dONLNd0EP*
  8254. 3                            IMPORT    our_A5 : CODE°dONLNddOZ!*
  8255. 5                            IMPORT    our_Buff : CODE°dONLNdöcn*4        LEA       our_A5, A0           ; this copies°dONLNdœmxô*
  8256. M        MOVE.L    CurrentA5, (A0)      ; this copies CurrentA5 into our local°dONLNdwÇ£*
  8257. O                                       ; storage for global use in the listener°dONLNdmÅåq*
  8258. E        MOVE.W    #DDPMaxData, D0      ; max size of data in a packet°dONLNd≥ãñã*
  8259.         _NewPtr   CLEAR°dONLNdÀï†N*
  8260. >        BNE.S     setUpFailed          ; if NIL then forget it°dONLNd
  8261. ©¥û*N        LEA       our_Buff, A1         ; we need to save the pointer reference°dONLNdY≥æô*
  8262. M        MOVE.L    A0, (A1)             ;  in a place the listener can find it°dONLNdßΩ»S*
  8263. ?        MOVE.L    A0, D0               ; return value to caller°dONLNdÁ«“O*
  8264.         RTS°dONLNdÛ—‹O*
  8265. setUpFailed°dONLNdˇ€Ê£*
  8266. O        CLR.L     D0                   ; tell caller we failed by returning nil°dONLNdOÂû*
  8267. N                                       ; (caller expecting valid ptr returned)°dONLNdûÔ˙O*
  8268.         RTS°dONLNd™T*         ENDP°dONLNd∑"O*         END
  8269. °dONLNd√-9Î*&We now resume our regular programming…°dONLNdÍEQ *0You should typically get an AEP response packet °dONLNdE Q⁄)Û*within a few milliseconds.  If there is no°dONLNdEQ]û(y6Rresponse for a period of time, typically about 10 seconds, you should resend your °dONLNdóQû]⁄(yº AEP request°dONLNd£]i$(Ö6to °dONLNd¶]$i⁄) Zaccount for a lost request or lost packets.  To be really safe, you should resend your AEP°dONLNdiuæ(ë6$request with different data to take °dONLNd%iæu⁄)¶9into account the response to the first packet coming back°dONLNd_vÇò(û6later.  The retry time could °dONLNd|vòÇ)Äthen be simply set to °dONLNdíuÅx)ik*Round_Trip_Time°dONLNd£vxÇ⁄)w, where the value of°dONLNd∏Çé&(´6k °dONLNd∫É&è-)9depends upon the request semantics, like total data size.°dONLNdÙõß(√64This technique of statically setting the retry time °dONLNd(õß⁄)Ï)is not always adequate to accommodate the°dONLNdRß≥°(œ6Tvarying delays encountered in a internet environment at different times.  You could °dONLNd¶ß°≥⁄(œø dynamically°dONLNd≤≥øñ(€6adjust the retry time based °dONLNdŒ≥ñø⁄)~Bon an adaptive retransmission algorithm that continuously monitors°dONLNdøÀX(Á6Around trip times and adjusts its timeout parameter accordingly.  °dONLNdRøXÀ⁄(ÁvTo implement an adaptive°dONLNdkÀ◊ï(Û6algorithm, you can record °dONLNdÖÀï◊⁄)}Bthe round trip time for each transaction.  One common technique is°dONLNd»◊„=(ˇ6to keep °dONLNd–◊=„⁄)%Sthe average round trip time as a weighted average and use new round trip times from°dONLNd$„ÔÇ( 6Gtransactions to change the average slowly.  For example, one averaging °dONLNdk„ÇÔµ( †
  8270. technique*
  8271.     °dONLNdu·µÏ∫(” 
  8272. °dONLNdv„∫Ô⁄+uses a°dONLNd}¸ì(6constant weighing factor, °dONLNdóÔì˚ö){q°dONLNdòö¸¡), where °dONLNd†Ô¡˚)'    0 ≤ q < 1°dONLNd©¸c)?, to weigh the oldest °dONLNdøc¸⁄)caverage against the latest°dONLNd⁄¸a($6round trip time:
  8273. °dONLNdΠÜ*=    W_aver = (q * W_aver ) + (( 1 - q) * New_Round_Trip_Time)
  8274. °dONLNd    ),8Ç*Choosing a value for °dONLNd    >+Ç7â)jq°dONLNd    ?,â8’)C close to 1 makes the weighted average immune to changes that last °dONLNd    Ç,’8⁄(TÛa°dONLNd    Ñ9E∑(a6"short time.  Choosing a value for °dONLNd    ¶8∑Dæ)üq°dONLNd    ß9æEË)
  8275.  close to °dONLNd    ±9ËE⁄)*/0 makes the weighted average respond to changes°dONLNd    ·EQê(m6in the delay very quickly.°dONLNd    ¸^j~*The total time (i.e., °dONLNd
  8276. ]~i5)fretry time * retry count)°dONLNd
  8277. +^5j–)∑ before a request is concluded °dONLNd
  8278. J^–j⁄)õas°dONLNd
  8279. Mjv¶(í6Rfailed could be anywhere from 10 seconds to a couple of minutes, depending on the °dONLNd
  8280. üj¶v⁄(íƒ type of the°dONLNd
  8281. ´vÇñ(û6Tclient application and the relative distance between the source and the destination. ¡4¡˘
  8282. *84) of 5(÷_"NW 14 - AppleTalk Timers Explained+8M.NW.AppleTalkTimerˇ®◊#ˇ ˇˇˇˇ#◊ 
  8283. IR,Times
  8284. .+Z-Developer Technical Support(-
  8285. April 1990 /X/
  8286. °dONLNd<(B(DZ*°dONLNdB+ë+>Douglass Corner, InterNetworking with TCP/IP. KARN, P. and C. °dONLNd?ë+˛(GØPARTRIDGE [August°dONLNdQ+<7‘(SZ1987], “Improving Round-Trip °dONLNdn+‘7ƒ)ò1Time Estimates in Reliable Transport Protocols”, °dONLNdü+ƒ7˛) Proceedings°dONLNd´7<Cπ(_Zof ACM SIGCOMM 1987°dONLNdæ7πCΩ)}.
  8287. °dONLNd¿[<j∂(ÜZNBP Retry Counts
  8288. °dONLNd—v<Ç#*0You cannot really use the AEP to estimate round °dONLNdv#Dz)Á+trip times for NBP packets because you need°dONLNd-Ç<é(™Z0to use NBP to determine the internet address of °dONLNd]Çé˛)‚,the node from which an echo is being sought.°dONLNdãé<öÕ(∂ZYIn this case, you have to use the type of device that you are looking for as a heuristic °dONLNd‰éÕö˛(∂Î for setting°dONLNdö<¶ú(¬ZDthe retry count.  The LaserWriter, for example, may be busy and not °dONLNd4öú¶˛(¬∫respond to a LkUp°dONLNdF¶<≤(ŒZ+packet.  In such a case, you might want to °dONLNdq¶≤˛) 6do a quick lookup to return a partial list to the user°dONLNd®≤<æ:(⁄Z5like the Chooser.  You could then do a longer lookup °dONLNd›≤:æ˛)˛(to get a more complete list of mappings.°dONLNdæ< U(ÊZYou °dONLNd æU ˛)Qshould use a “back off” algorithm to make the subsequent lookups further apart to°dONLNd] <÷,(ÚZ3generate progressively less traffic.  Name lookups °dONLNdê ,÷˛)*are expensive and produce a lot of network°dONLNdª÷<‚`(˛Z:traffic, and name confirmation is the recommended call to °dONLNdı÷`‚˛(˛~use when confirming mappings°dONLNd‚<Óh(
  8289. Z    obtained °dONLNd‚hÓ˛),Mthrough early bindings.  Because Name lookups are expensive, you should avoid°dONLNdiÓ<˙Ì(Z(searching all the zones in the internet.
  8290. °dONLNdí<!&*'!Setting TRel Timer in SendRequest
  8291. °dONLNd¥.<: *$AppleTalk Phase 2 drivers allow you °dONLNdÿ. :û)–to set the TRel timer in ,
  8292. Courier°dONLNdÒ-û9Î)í SendRequest°dONLNd¸.Î:˛)M or°dONLNd:<Fò(cZ
  8293. NSendRequest °dONLNd
  8294. ;òGt)\,calls with ATP XO (exactly once) service so °dONLNd9;tG˛)‹as not to be locked into the°dONLNdVG<S (oZ*pre-AppleTalk Phase 2 time of 30 seconds. °dONLNdÄG S˛)œ2 You should set this timer based on the round trip°dONLNd≥S<_*({Z6time.  Generally, if the round trip time is less than °dONLNdÈS*_˛)Ó,one second, the default TRel time setting of°dONLNd_<k…(áZ30 seconds is adequate.  If °dONLNd2_…k˛)ç;the round trip time is more, you can increase the TRel time°dONLNdnk<wà(ìZproportionately.
  8295. °dONLNdè<ûÈ*'xppTimeout and xppRetry
  8296. °dONLNdó´<∑ó*The two ZIP calls, °dONLNd™™ó∂‰)[ GetZoneList°dONLNdµ´‰∑˚)M and °dONLNd∫™˚∂V)
  8297. GetLocalZones°dONLNd«´V∑˛)[!, made on the .XPP driver contain°dONLNdÈ∏<ƒ(‡Z(the ATP retry interval (in seconds) and °dONLNd∏ƒ_)÷count, in the °dONLNd∑_√•)M
  8298. xppTimeout°dONLNd)∏•ƒΔ)F and °dONLNd.∑Δ√˛)!xppRetry°dONLNd7ƒ<–ï(ÏZHparameters.  Both these functions are ATP request-response transactions °dONLNdƒï–˛(Ï≥between a node and a°dONLNdî–<‹E(¯Z6router on the network to which the requesting node is °dONLNd –E‹˛(¯c'attached.  The round trip is relatively°dONLNdÚ›<Ȱ(ZEshort for this transaction, and you should have very small values of °dONLNd7‹°ËÁ(ø
  8299. xppTimeout°dONLNdA›ÁÈÌ)F °dONLNdB›ÌÈ˛)and°dONLNdFÈ<ı{(Z    xppRetry,°dONLNdOÍ{ˆ,)?' typically two and three, respectively.°dONLNdw<&¶(BZFurther Reference: EXE°dONLNdä'N3R+
  8300. •°dONLNdå'`3±)Inside AppleTalk°dONLNdù3N?R([l•°dONLNdü3`?})7Inside Macintosh, Volumes II & V, The AppleTalk Manager°dONLNd◊?NKR(gl•°dONLNdŸ?`KØ)M.NW.Internets°dONLNdËKNWR(sl•°dONLNdÍK`W—)M.NW.AppleTalk2Mac ¡X¡
  8301. (÷Z"NW 14 - AppleTalk Timers Explained(÷5) of 5(ÏZM.NW.AppleTalkTimerˇû◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  8302. /ZÅ#
  8303.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  8304. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  8305. .WIQkWIQk+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  8306. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  8307. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  8308.     l+&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  8309. BÄ(Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É°dWORD†ç
  8310. IR.°dONLNdo<Ç?(úZNW 15 - Arbitrating the Use of°dONLNdÅ<îµ*'afpMiscUserCommand and afpMiscUserWrite
  8311. °dONLNdGì<¢ä*
  8312. Networking
  8313. °dONLNdSÆ<∫q* Written by:°dONLNd_ÆÑ∫∑)H
  8314. Jim Luther°dONLNdjƱ∫˛(÷œSeptember 1992 °dONLNdyΔ<“
  8315. (ÓZ This Technical Note discusses a  °dONLNdôΔ
  8316. “˛)—%scheme for arbitrating the use of the,
  8317. Courier°dONLNdø“<fi∫(˚ZafpMiscUserCommand°dONLNd—”∫fl€)~ and °dONLNd÷“€fiK)!afpMiscUserWrite°dONLNdÊ”Kfl‡)p AppleTalk Filing Protocol °dONLNd”‡fl˛)ï(AFP)°dONLNdfl<Îs(Z    commands. X°dONLNd<é*%Inside Macintosh°dONLNd!ét)R+ Volume V lists two AFP command codes that °dONLNdLt˛)Êare reserved for developers.°dONLNdi<p(9Z    They are °dONLNdrpÓ)4afpMiscUserCommand°dONLNdÑÓ;)~ (call number °dONLNdí;r)M    191) and °dONLNdõr‚)7afpMiscUserWrite°dONLNd´‚˛)p (call°dONLNd≤<)˙(EZ%number 254). Several developers have °dONLNd◊˙)˛)æ3asked that Apple arbitrate the use of those two AFP°dONLNd )<5k(QZ>calls. This Technical Note describes our recommended solution.°dONLNdJB<Ng*Because °dONLNdRAgMÂ)+afpMiscUserCommand°dONLNddBÂNÈ)~ °dONLNdeBÈNˇ)and °dONLNdiAˇMo)afpMiscUserWrite°dONLNdyBoN˛)p are reserved for developers,°dONLNdóN<Z∞(vZLthe format of the AFP request and reply blocks are undefined except for the °dONLNd„N∞Z˛(vŒfirst byte of the°dONLNdıZ<f|(ÇZArequest block which contains the AFP call number. If the request °dONLNd6Z|f˛(Çöblock is further defined to°dONLNdRf<r˜(éZ(include a word-aligned long value, that °dONLNdzf˜r˛)ª7long value can be used to identify a specific developer°dONLNd≤r<~¢(öZrequest. Since most °dONLNdΔr¢~˛)fCdevelopers have probably already been assigned a unique 4-byte file°dONLNd
  8318. ~<ä\(¶Z;creator type, we suggest reusing that creator type for the °dONLNdE~\ä˛(¶zlong value. Figure 1 shows the°dONLNddã<óî(≥Zrequest blocks for °dONLNdwäîñ)XafpMiscUserCommand°dONLNdâãó))~ and °dONLNdéä)ñô)afpMiscUserWrite°dONLNdûãôó¥)p with °dONLNd§ã¥ó˛)the creator type°dONLNdµò<§¶(¿Zvalue. The value of °dONLNd…ó¶£)j
  8319. aspMaxCmdSize°dONLNd÷ò§L)[ in the figure °dONLNdÂòL§±)Kis returned by the °dONLNd¯ó±£˛)e ASPGetParms°dONLNd§<∞g(ÃZ    function.†Ç†å
  8320. €ûâÿ0›¢!0Ô¢!0¢J!"¢    "%¢    "7¢    "    "%    "7    0›V’0ÔV’0VJ’"V    "%V    "7V    "À    "%À    "7À    °ñ °öˇ˝7
  8321. ‡©Ï.Æ:Æ:°dONLNdˇˇ+PafpMiscUserCommand †ó°ñ °öˇ˝
  8322. Úfi˛Âv°dONLNdˇˇ+50†ó°ñ °öˇ¸(
  8323. ≤+v°dONLNdˇˇ((πyour creator type†ó°ñ °öˇ¸,
  8324. ·hÌ√i¿°dONLNdˇˇ(ÍiafpMiscUserWrite†ó°ñ °öˇ˝
  8325. Úí˛ô∞İdONLNdˇˇ+*0†ó
  8326. €ûâÿ"I¢    "I     "¢    "     "à¢~°ñ °ö    
  8327. Vüz•°dONLNdˇˇ(_†•
  8328. ≤¿°dONLNdˇˇ* •
  8329. ÂİdONLNdˇˇ* •†ó°ñ °ö    
  8330. Vz#@°dONLNdˇˇ(_•
  8331. K°dONLNdˇˇ* •
  8332. }¿°dONLNdˇˇ* •†ó
  8333. €ûâÿ"IV    "I‘    "V    "‘    "àV~°ñ °ö    
  8334. VSzY°dONLNdˇˇ(_T•
  8335. ≤¿°dONLNdˇˇ* •
  8336. ÂİdONLNdˇˇ* •†ó°ñ °ö    
  8337. V—z◊@°dONLNdˇˇ(_“•
  8338. K°dONLNdˇˇ* •
  8339. }¿°dONLNdˇˇ* •†ó°ñ °ö     
  8340. V∞z∞İdONLNdˇˇ(_÷up to
  8341. °dONLNdˇˇ(k±aspMaxCmdSize - 6
  8342. ˇÄ°dONLNdˇˇ+$ bytes†ó°ñ °ö     
  8343. Vdz«S@°dONLNdˇˇ(_äup to
  8344. ®¿°dONLNdˇˇ(keaspMaxCmdSize - 6
  8345. ¢@°dONLNdˇˇ+$ bytes†ó°ñ °öˇ¸(
  8346. f+≈ˆ°dONLNdˇˇ((myour creator type†ó†ç†É
  8347. IR.°dONLNdvÇ∫(ûù1Figure 1  afpMiscUserCommand and afpMiscUserWrite°dONLNd@Çûéú+ +Request Blocks With Creator Type Identifier ¿X¿
  8348. (÷ZFNW 15 - Arbitrating the Use of afpMiscUserCommand and afpMiscUserWrite(÷1) of 2(ÏZ"M.NW.ArbitratingafpMiscUserCommandˇ°¿Ù%%DSIDICT:_cv
  8349. currentdict /bu known {bu}if
  8350. userdict /_cv known not{userdict /_cv 30 dict put}if
  8351. _cv begin
  8352. /bdf{bind def}bind def
  8353. currentscreen/cs exch def/ca exch def/cf exch def
  8354. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  8355. /ss{//cf //ca //cs setscreen}bdf
  8356. /stg{ss setgray}bdf
  8357. /strgb{ss setrgbcolor}bdf
  8358. /stcmyk{ss cvcmyk}bdf
  8359. /min1{dup 0 eq{pop 1}if}bdf
  8360. end
  8361. currentdict /bn known {bn}if
  8362. †ø◊#ˇ ˇˇˇˇ#◊ 
  8363. IR,Times
  8364. .+6-Macintosh Technical Notes /4/˘
  8365. °dONLNd5AÇ*0Further Reference: `4`˘°dONLNdB*N.+
  8366. •°dONLNdB<N=)1Inside Macintosh, Volume V, The AppleTalk Manager°dONLNdGN*Z.(vH•°dONLNdIN<Z®)M.NW.BorrowedAFP ¿4¿˘
  8367. (÷62) of 2)ÜFNW 15 - Arbitrating the Use of afpMiscUserCommand and afpMiscUserWrite+ë"M.NW.ArbitratingafpMiscUserCommandˇ∏◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  8368. /ZÅ#
  8369.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  8370. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  8371. .WIQkWIQk+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  8372. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  8373. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:    °öˇ˝Ä†ò
  8374.     l+&    ®†ô°ddrw2:°„†ó°d1drw2Â-¯yˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚Ä%†ò
  8375. BÄ(Z\    Macintosh†ô°ddrw2:°„†ó†ç°ddrw2D†É°dWORD†ç
  8376. IR.°dONLNdˇˇ(õZNW 16 - Borrowed AFP Sessions
  8377. °dONLNdˇˇ* Networking 
  8378. °dONLNdˇˇ* Written by:°dONLNdˇˇ)H
  8379. Jim Luther°dONLNdˇˇ(¬œSeptember 1992°dONLNdˇˇ(ŸZEThis Technical Note shows how to borrow the session reference number °dONLNdˇˇ(Ÿøof an AFP volume°dONLNdˇˇ(ÂZmounted by the °dONLNdˇˇ)LKMacintosh File System. It also shows how to retrieve other information from°dONLNdˇˇ(ÒZ)the file system for a mounted AFP volume. ˇXˇ
  8380. °dONLNdˇˇ*' Introduction
  8381. °dONLNdˇˇ*The AppleShare Chooser °dONLNdˇˇ)É=extension allows Macintosh applications to perform almost all°dONLNdˇˇ(?ZTvolume and file access operations on an AppleTalk Filing Protocol (AFP) file server °dONLNdˇˇ(?by°dONLNdˇˇ(KZPtranslating File Manager commands to their AFP equivalent commands. To access a °dONLNdˇˇ(KË file server,°dONLNdˇˇ(WZ4an application normally calls the File Manager. The °dONLNdˇˇ)Ù*File Manager calls the AppleShare external°dONLNdˇˇ(cZ$file system (part of the AppleShare °dONLNdˇˇ)≥4Chooser extension) which translates the File Manager°dONLNdˇˇ(oZ7command into an AFP call. The AppleShare external file °dONLNdˇˇ(op"system then calls the .XPP driver.°dONLNdˇˇ({Z4The .XPP driver delivers the AFP call to the server °dONLNdˇˇ)˛'and returns the reply to the AppleShare°dONLNdˇˇ(áZexternal file system. °dONLNdˇˇ)bJThe AppleShare external file system translates the reply data (if any) and°dONLNdˇˇ(ìZDreturns it to the File Manager which returns it to the application. °dONLNdˇˇ(ìïFigure 1 shows the normal°dONLNdˇˇ(üZHflow of commands between a Macintosh application and an AFP file server.†Ç†å
  8382. Æóõfi0∞ô’0Ôô0.ô\0vôõ" ††°§
  8383. 
  8384. "”˜    ####    ##˚##        ##    ˜##¸##˜####˜˜#†£
  8385. Æóõfi#˜    ##    #˚#        #    ˜#¸#˜##˜˜†°"d ††°§
  8386. 
  8387. "[”˜    ####    ##˚##        ##    ˜##¸##˜####˜˜#†£
  8388. Æóõfi#˜    ##    #˚#        #    ˜#¸#˜##˜˜†°°ñ °öˇ¸
  8389. º∂».ÌGÌG°dONLNdˇˇ+]& Application†ó°ñ °öˇ˝ 
  8390. ˚≤Ù&¿°dONLNdˇˇ(≥ File Manager†ó°ñ °öˇ¸
  8391. Ç∂étİdONLNdˇˇ+á .XPP driver†ó°ñ °öˇ¸$
  8392. Ç}é»@°dONLNdˇˇ)«AFP file server†ó
  8393. Æóõfi"› ††°§
  8394. ¸
  8395. "‘”˜    ####    ##˚##        ##    ˜##¸##˜####˜˜#†£
  8396. Æóõfi#˜    ##    #˚#        #    ˜#¸#˜##˜˜†°0vhõfi°d
  8397. MDPL    †åqÉäàÉÜäà"Ü#˝†ç°dMDPL
  8398. #˜    °d
  8399. MDPL    †åqÖYåhàhåZâYÖYàh##˝†ç°dMDPL
  8400. °ñ °öˇ˝
  8401. w!ÉT
  8402. °dONLNdˇˇ(Ä" AFP session†ó°ñ °ö0
  8403. 2°V
  8404. 8¿°dONLNdˇˇ(;£AppleShare external Ä@°dONLNdˇˇ+ file system / &İdONLNdˇˇ(SØ.AFPTranslator†ó†ç†É
  8405. IR.°dONLNdˇˇ(∞tDFigure 1  Application Using the File Server Through the File Manager ¡X¡
  8406. (÷ZNW 16 - Borrowed AFP Sessions(÷1) of 8(ÏZM.NW.Borrowed AFPˇ°¿Ù%%DSIDICT:_cv
  8407. currentdict /bu known {bu}if
  8408. userdict /_cv known not{userdict /_cv 30 dict put}if
  8409. _cv begin
  8410. /bdf{bind def}bind def
  8411. currentscreen/cs exch def/ca exch def/cf exch def
  8412. /setcmykcolor where{/setcmykcolor get /cvcmyk exch def}{/cvcmyk{1 sub 4 1 roll 3{3 index add neg dup 0 lt{pop 0}if 3 1 roll}repeat setrgbcolor pop}bdf }ifelse
  8413. /ss{//cf //ca //cs setscreen}bdf
  8414. /stg{ss setgray}bdf
  8415. /strgb{ss setrgbcolor}bdf
  8416. /stcmyk{ss cvcmyk}bdf
  8417. /min1{dup 0 eq{pop 1}if}bdf
  8418. end
  8419. currentdict /bn known {bn}if
  8420. †øö◊#ˇ ˇˇˇˇ#◊ 
  8421. IR,Times
  8422. .+6-Macintosh Technical Notes /4/˘
  8423. °dONLNd)5K*$    However, °dONLNd    )K5⁄)3Pthere are a few instances for which no equivalent File Manager commands exist to°dONLNdZ5Aó(]6Mperform operations supported by AFP. In those instances, an application must °dONLNdß5óA⁄(]µ use the .XPP°dONLNd¥AM(i63driver to access the file server with AFP commands.°dONLNdËYep*DApplications accessing a file server with AFP commands need to have °dONLNd,Ype⁄(Åéan open AFP session°dONLNd@eqÌ(ç6.with the file server. When no session exists, °dONLNdneÌq⁄)’0the application must use the .XPP driver to open°dONLNdür~ì(ö6an AFP session with the ,
  8424. Courier°dONLNd∑qì}À){afpLogin°dONLNdørÀ~œ)8 °dONLNd¿rœ~)(and possibly °dONLNdŒq}j)G afpLoginCont°dONLNd⁄rj~⁄)T) command. However,°dONLNdÓ~äí(¶6Jwhen an AFP volume on the file server is already mounted by the Macintosh °dONLNd8~íä⁄(¶∞File System, a°dONLNdGäñ>(≤6session °dONLNdOä>ñ⁄)&Wis already open with the file server. If the session reference number is retrieved from°dONLNdßñ¢£(æ6Sthe .AFPTranslator driver (another part of the AppleShare Chooser extension), that °dONLNd˙ñ£¢⁄(æ¡ session can°dONLNd¢Æ&( 6be °dONLNd    ¢&ÆD)used, °dONLNd¢DÆë)with restrictions°dONLNd ¢ëÆ⁄)MA, to access the file server with AFP commands. Figure 2 shows the°dONLNdbÆ∫ô(÷6flow of commands when a °dONLNdzÆô∫⁄)ÅBMacintosh application accesses an AFP file server directly through°dONLNdΩ∫Δÿ(‚6[the .XPP driver using the session reference number borrowed from the .AFPTranslator driver.†Ç†å
  8425. Ò=fi0Û´!    ™U™U™U™U02´W!    ˇˇˇˇˇˇˇˇ0q´ü!0π´fi!"_‹††°§
  8426.     
  8427. "V˜    ####    ##˚##        ##    ˜##¸##˜####˜˜#†£
  8428. Ò=fi#˜    ##    #˚#        #    ˜#¸#˜##˜˜†°"ß‹††°§
  8429.     
  8430. "û˜    ####    ##˚##        ##    ˜##¸##˜####˜˜#†£
  8431. Ò=fi#˜    ##    #˚#        #    ˜#¸#˜##˜˜†°°ñ °öˇ¸
  8432. ˇ» .Ì≥Ì≥°dONLNdˇˇ+ì& Application†ó°ñ °öˇ˝ 
  8433. >ƒJ&¿°dONLNdˇˇ(G≈ File Manager†ó°ñ °öˇ¸
  8434. ≈»—tİdONLNdˇˇ+á .XPP driver†ó°ñ °öˇ¸$
  8435. ≈è—⁄@°dONLNdˇˇ)«AFP file server†ó
  8436. Ò=fi"ÉZ††°§
  8437. ¸
  8438. "É´Ø##˚##˜##    
  8439. ##¸##Q##Ó#†£
  8440. Ò=fi#Ø#˚#˜#    
  8441. #¸#Q#Ó†°°ñ °öˇ˝
  8442. Ücí°
  8443. °dONLNdˇˇ(èdsession refnum†ó
  8444. Ò=fi"¢††°§
  8445. ˝
  8446. "¢¸##Ø#!¬Q##Q##˚##    ##˜
  8447. ##¸##ù#!¸?##c##˚##    ##˜
  8448. #†£
  8449. Ò=fi#¸#Ø!¬Q#Q#˚#    #˜
  8450. #¸#ù!¸?#c#˚#    #˜
  8451. †°°ñ °öˇ¸&
  8452. ˇS ¢,    Symbol°dONLNdˇˇ(T¨
  8453. ^@°dONLNdˇˇ)
  8454. ^@°dONLNdˇˇ) AFP commands†ó
  8455. Ò=fi" ‹††°§
  8456. ¸
  8457. "˜    ####    ##˚##        ##    ˜##¸##˜####˜˜#†£
  8458. Ò=fi#˜    ##    #˚#        #    ˜#¸#˜##˜˜†°0πzfi°d
  8459. MDPL    †åqΔ Õ.À Δ-….Õ.À "….#˝†ç°dMDPL
  8460. #˜    °d
  8461. MDPL    †åq»kœzÀzœlÃk»kÀz##˝†ç°dMDPL
  8462. °ñ °öˇ˝
  8463. ∫3Δf°dONLNdˇˇ+”ª AFP session†ó°ñ °öˇ¸
  8464. ≈[—ô8¿°dONLNdˇˇ(Œ\¨
  8465. °dONLNdˇˇ)
  8466. °dONLNdˇˇ) AFP replies†ó°ñ °ö0
  8467. u≥ô
  8468. 쇰dONLNdˇˇ(~µAppleShare external €`°dONLNdˇˇ+ file system / ņ°dONLNdˇˇ(ñ¡.AFPTranslator†ó†ç†É
  8469. IR.°dONLNdÀ>◊¥(Û\?Figure 2  Application Using File Server Through the .XPP Driver°dONLNdY◊„Ü(ˇ6E                               with Borrowed Session Reference Number°dONLNdüÔ˚√*ZThe next section of this Technical Note tells how to get the AFP session reference number °dONLNd˘Ô√˚⁄(·for a°dONLNdˇ˚0(#66mounted AFP volume from the .AFPTranslator driver. It °dONLNd5˚0⁄(#N$also lists the restrictions you must°dONLNdZ¸(/6,observe when using the borrowed AFP session.
  8470. °dONLNdá+:;*')The Server Volume Information Status Call
  8471. °dONLNd±FRí*The AppleShare external °dONLNd…FíR⁄)z@file system performs the translation of File Manager commands to°dONLNd
  8472. R^Ó(z6)AFP commands and maintains sessions with °dONLNd3RÓ^⁄)÷/AFP file servers. The server volume information°dONLNdc_k(á6(°dONLNdd^ji) AFPSVolInfo°dONLNdo_ik)M%)  status call to the .AFPTranslator °dONLNdî_k⁄)≥&driver can be used to retrieve several°dONLNdªkwâ(ì6Fimportant pieces of information stored by the driver. The information °dONLNdkâw⁄(ìßreturned by the°dONLNdwÉe(†6 AFPSVolInfo°dONLNdxeѧ)M status call is: ¡4¡˘
  8473. (÷62) of 8(÷qNW 16 - Borrowed AFP Sessions+0M.NW.BorrowedAFPˇ:◊#ˇ ˇˇˇˇ#◊ 
  8474. IR,Times
  8475. .+Z-Developer Support Center(-€September 1992 /X/
  8476. °dONLNdN)R(El•°dONLNd[)Æ)
  8477. the AFP version °dONLNdÆ)˛)SAused to open the session with the server. This lets you know what°dONLNdT)[5F(Qy1possible AFP calls can be made with this session.°dONLNdÜANMR(il•°dONLNdàA[Mb)
  8478. 4the session reference number. The session reference °dONLNdºAbM˛(iÄnumber is passed to the .XPP°dONLNdŸM[Y(uy%driver whenever you make an AFP call.°dONLNdˇeNqR(çl•°dONLNde[qÖ)
  8479. the AFP °dONLNd    eÖq˛)*Kvolume ID number. This is the number you pass to AFP calls that require the°dONLNdUq[}∏(ôyvolume ID number.°dONLNdgâNïR(±l•°dONLNdiâ[ïØ)
  8480. Lthe file server’s internet socket address. This is the same internet socket °dONLNdµâØï˛(±Õaddress returned°dONLNdΔñ[¢ì(æy by the File °dONLNd“ñ좡)8Manager ,
  8481. Courier°dONLNd⁄ï¡°#).PBHGetVolParms°dONLNdËñ#¢u)b function in the °dONLNd˘ïu°¬)R vMServerAdr°dONLNdñ¬¢˛)M
  8482.  field of the°dONLNd¢[ÆÓ(ÀyGetVolParmsInfoBuffer°dONLNd'£ÓØ)ì record.°dONLNd0ªN«R(„l•°dONLNd2ª[«?)
  8483. -the user authentication method (UAM) used to °dONLNd_ª?«˛)‰'establish the session. This is the same°dONLNdá»[‘O(y(word value returned by the File Manager °dONLNdØ«O”∏)ÙPBHGetLogInInfo°dONLNdæ»∏‘˛)i  function in°dONLNdÀ‘[‡ö(˝y    ioObjType°dONLNd‘’ö·0)? and by the File Manager °dONLNdÌ‘0‡ß)ñPBGetVolMountInfo°dONLNd˛’ß·fi)w
  8484.  function °dONLNd’fi·˛)7in the°dONLNd·[Ìå(
  8485. yuamType°dONLNd‚åÓ≈)1 field of the °dONLNd$·≈Ì.)9AFPVolMountInfo°dONLNd3‚.ÓS)i record.°dONLNd<˙NR("l•°dONLNd>˙[)
  8486.  the user name used to establish °dONLNd^˙˛)ï9the session. This is the same string returned by the File°dONLNdò[à(/yManager °dONLNd†àÒ)-PBHGetLogInInfo°dONLNdØÒ™)i& function in the string pointed to by °dONLNd’™˛)π ioObjNamePtr°dONLNd‚[ –(<yand by the File Manager °dONLNd˙–G)uPBGetVolMountInfo°dONLNd G ¥)w function as part of the °dONLNd$¥Â)mAFPData°dONLNd+ ˛)1 field°dONLNd2![-x(Iyin the °dONLNd9 x,·)AFPVolMountInfo°dONLNdH!·-Æ)i- record (the exact location of the user name °dONLNdu!Æ-Õ)Õin the °dONLNd| Õ,˛)AFPData°dONLNdÑ.[:ô(Vy
  8487. field in the °dONLNdë-ô9)>AFPVolMountInfo°dONLNd†.:t)i record is determined °dONLNd∂.t:ú)rby the °dONLNdΩ-ú9˛)(userNameOffset°dONLNdÃ:[Fx(byfield).°dONLNd‘RN^R(zl•°dONLNd÷R[^◊)
  8488. Kthe server’s volume icon and mask. This is the same 256-byte icon and mask °dONLNd!R◊^˛(zıreturned°dONLNd*_[k(áy*by a control call to the disk driver with °dONLNdT^j>)πcsCode°dONLNdZ_>k[)* = 21.°dONLNdawNÉR(ül•°dONLNdcw[Ɉ)
  8489. Uthe string displayed by the Finder’s Get Info dialog (after the word “Where:”). This °dONLNd∏wˆÉ˛(üis°dONLNdªÑ[êà(¨yCthe same string returned by a control call to the disk driver with °dONLNd˛Éàè≤(¨¶csCode°dONLNdÑ≤êœ)* = 21.°dONLNd ù<©-(≈Z*The information list above is returned in °dONLNd5ù-©=)Òa °dONLNd7ú=®¥)GetVolSessInfoRec°dONLNdHù¥©˛)w  record. The°dONLNdU©<µ≥(“ZGetVolSessInfoRec°dONLNdf™≥∂<)w record is defined as follows:
  8490.     °dONLNdÖ¬<Õ“(ÈZ    GetVolSessInfoRec = RECORD°dONLNd§Ã<◊m*
  8491. =        sessAFPVersion: Integer;       {AFP version number: }°dONLNd‚÷<·m*
  8492. =                                       {    1 = version 1.1 }°dONLNd ‡<Îm*
  8493. =                                       {    2 = version 2.0 }°dONLNd^Í<ım*
  8494. =                                       {    3 = version 2.1 }°dONLNdúÙ<ˇÅ*
  8495. A        sessReferenceNumber: Integer;  {session reference number}°dONLNdfi˛<    r*
  8496. >        sessAFPVolID: Integer;         {AFP volume identifier}°dONLNd<|*
  8497. @        sessServerAddress: AddrBlock;  {server internet address}°dONLNd^<ï*
  8498. E        sessUAMType: Integer;          {user authentication method: }°dONLNd§<'ã*
  8499. C                                       {    1 = 'No User Authent' }°dONLNdË&<1ê*
  8500. D                                       {    2 = 'Cleartxt Passwrd' }°dONLNd    -0<;ê*
  8501. D                                       {    3 = 'Randnum Exchange' }°dONLNd    r:<EÆ*
  8502. J                                       {    6 = '2-Way Randnum exchange' }°dONLNd    ΩD<O|*
  8503. @        sessUserNamePtr: StringPtr;    {ptr to user name string}°dONLNd    ˛N<Yü*
  8504. G        sessVolIconPtr: Ptr;           {ptr to server volume icon/mask}°dONLNd
  8505. FX<cÆ*
  8506. J        sessWhereStringPtr: StringPtr; {ptr to "where" information string}°dONLNd
  8507. ëb<mn*
  8508.  
  8509.       END; ¡X¡
  8510. *MNW 16 - Borrowed AFP Sessions(÷3) of 8(ÏZM.NW.BorrowedAFPˇ¯◊#ˇ ˇˇˇˇ#◊ 
  8511. IR,Times
  8512. .+6-Macintosh Technical Notes /4/˘
  8513. °dONLNd*L*Warning:,
  8514. Courier6°dONLNd    `)…)HsessUserNamePtr°dONLNd…*)i, °dONLNd)h)=sessVolIconPtr°dONLNd(h*•)b, 7°dONLNd*•*∂)=and°dONLNd.*`6fi(S~sessWhereStringPtr°dONLNd@+fi7 )~
  8515.  point to °dONLNdJ+ 7∂)- data owned by the .AFPTranslator°dONLNdk7`C÷(_~driver. You must copy °dONLNdÅ7÷C∂)v,that data into your program variables before°dONLNdÆC`Oá(k~    using it.°dONLNd∏\ho(Ñ6The fields in the °dONLNd [og )W
  8516. ParamBlockRec°dONLNd◊\ h3)[ record used for the °dONLNdÏ[3gÄ)i AFPSVolInfo°dONLNd˜\Äh⁄)M status call to the°dONLNd htÔ(ê6-.AFPTranslator driver are defined as follows:,    Symbol
  8517. °dONLNd9Åå"*Æ
  8518. °dONLNd;Å<çH)$12°dONLNd>ÄWå´) ioCompletion°dONLNdKÅ√çÿ)llong°dONLNdPÅ˘çÅ)6pointer to completion routine
  8519. °dONLNdnéô"(∂6¨
  8520. °dONLNdpé<öH)$16°dONLNdsçWôè)ioResult°dONLNd|é√ö‹)lword°dONLNdÅé˘ö,)6 result code
  8521. °dONLNdçõ¶"(√6Æ
  8522. °dONLNdèõ<ßH)$24°dONLNdíöW¶è)ioRefNum°dONLNdõõ√ß‹)lword°dONLNd†õ˘ßò)6.AFPTranslator reference number
  8523. °dONLNd¿®≥"(–6Æ
  8524. °dONLNd¬®<¥H)$26°dONLNd≈ßW≥Å)csCode°dONLNdî√¥‹)lword°dONLNd—®˘¥)6always °dONLNdÿß≥j)$ AFPSVolInfo
  8525. °dONLNd‰µ¿"(›6Æ
  8526. °dONLNdʵ<¡H)$28°dONLNdÈ¥W¿Å)ioMisc°dONLNdµ√¡ÿ)llong°dONLNdıµ˘¡X)6pointer to volume’s °dONLNd    ¥X¿m)_VCB
  8527. °dONLNd
  8528. ¬Õ"(Í6Æ
  8529. °dONLNd¬<ŒH)$32°dONLNd¡WÕè)ioBuffer°dONLNd¬√Œÿ)llong°dONLNd ¬˘Œ))6 pointer to °dONLNd+¡)Õ†)0GetVolSessInfoRec
  8530. °dONLNd=œ⁄"(˜6Æ
  8531. °dONLNd?œ<€H)$36°dONLNdBŒW⁄ù)
  8532. ioReqCount°dONLNdMœ√€ÿ)llong°dONLNdRœ˘€^)6size of data requested
  8533. °dONLNdi‹Á"(6¨
  8534. °dONLNdk‹<ËH)$40°dONLNdn€WÁù)
  8535. ioActCount°dONLNdy‹√Ëÿ)llong°dONLNd~‹˘ËX)6size of data returned°dONLNdîÙ@(6AHere are the detailed descriptions of the parameter block fields:°dONLNd÷ *~+ ioCompletion°dONLNd„
  8536. Ã)¢    Longword °dONLNdÏ
  8537. m)6input pointer:  If the °dONLNd m∫)k AFPSVolInfo°dONLNd
  8538. ∫⁄)M status°dONLNdÃ% (AÍcell is called °dONLNd% %⁄)?)asynchronously, this must be a pointer to°dONLNdO%Ã1](MÍthe completion routine or NIL.°dONLNdn1*=b(ZHioResult°dONLNdw2Ã> )¢6Word result value:  The result code from the function.°dONLNdÆ>*Jb(gHioRefNum°dONLNd∑?ÃK')¢Word input value: °dONLNd…?'K⁄)[# The driver reference number of the°dONLNdÌKÃW9(sÍ.AFPTranslator driver.°dONLNdW*cT(ÄHcsCode°dONLNd XÃdN)¢Word input value:  Always °dONLNd%WNcõ)Ç AFPSVolInfo°dONLNd0Xõdº)M (124).°dONLNd8d*pT(çHioMisc°dONLNd?eÃqR)¢Longword input pointer:  °dONLNdXeRq⁄)ÜA pointer to the volume’s°dONLNdrrÃ~7(öÍvolume control block (°dONLNdàq7}L)kVCB°dONLNdãrL~T)).°dONLNdé~*äb(ßHioBuffer
  8539. °dONLNdóÃã0)¢Longword input  °dONLNd¶0ã⁄)dpointer:  A pointer to the°dONLNd¡ãÃóC(¥ÍGetVolSessInfoRec°dONLNd“åCò∑)w where the server     °dONLNd‰å∑ò⁄)tvolume°dONLNdÎòç<(¿Íinformation is returned.°dONLNd§*∞p(ÕH
  8540. ioReqCount °dONLNd•ñn)¢Longword input value:  
  8541. °dONLNd&•n±⁄)¢The size of the°dONLNd6±ÃΩC(⁄ÍGetVolSessInfoRec°dONLNdG≤Cæá)w pointed to by °dONLNdV±áΩø)DioBuffer°dONLNd^≤øæ√)8.°dONLNd`æ* p(ÁH
  8542. ioActCount°dONLNdkøÃÀ)¢    Longword °dONLNdtøÀ⁄)5/result value:  The size of the data returned in°dONLNd§ÃÃÿ›(ÙÍthe °dONLNd®À›◊T)GetVolSessInfoRec°dONLNdπÃTÿò)w pointed to by °dONLNd»Àò◊–)DioBuffer°dONLNd–Öÿ‘)8.°dONLNd“ÂÒ(
  8543. 62The following result codes can be returned by the °dONLNd‰Q)Ï AFPSVolInfo°dONLNdÂQÒÖ)M
  8544.  status call:°dONLNd˝<    _(&ZnoErr°dONLNd#˛¢
  8545. ®)f0°dONLNd%˛Ã
  8546. ˘)*    No error.°dONLNd/
  8547. <Ç(3Z
  8548. badUnitErr°dONLNd: ò®)\-21°dONLNd> Ãu)4#The driver reference number is bad.°dONLNdb<#ê(@Z unitEmptyErr°dONLNdoò$®)\-22°dONLNdsÃ$u)4#The driver reference number is bad.°dONLNdó$<0Ç(MZ
  8549. notOpenErr°dONLNd¢%ò1®)\-28°dONLNd¶%Ã13)4The driver isn’t open.°dONLNdΩ1<={(ZZ    statusErr°dONLNd«2ò>®)\-18°dONLNdÀ2Ã>ï)4-The driver can’t respond to this status call.°dONLNd˘><Jt(gZparamErr°dONLNd?òK®)\-50$°dONLNd?ÃK)4Either °dONLNd
  8550. >JU)C
  8551. ioReqCount°dONLNd?UKÃ)F  indicates %°dONLNd"?ÃK⁄)wthe°dONLNd&KÃWC(tÍGetVolSessInfoRec°dONLNd7LCX~)w  record is °dONLNdBL~X⁄);too small, or the°dONLNdTYÃe:(ÅÍvolume specified by °dONLNdhX:dd)nioMisc°dONLNdnYdeê)* is not °dONLNdvYêe⁄), owned by the°dONLNdÉeÃq9(çÍ.AFPTranslator driver.°dONLNdö~ä·(¶6(The following code shows how to use the °dONLNd¬}·â.)… AFPSVolInfo°dONLNdÕ~.ä⁄)M% status call to get the server volume°dONLNdÛäñ`(≤6Dinformation for the volume specified by its volume reference number. ¡4¡˘
  8552. *$4) of 8(÷qNW 16 - Borrowed AFP Sessions+0M.NW.BorrowedAFPˇz◊#ˇ ˇˇˇˇ#◊ 
  8553. IR,Times
  8554. .+Z-Developer Support Center(-€September 1992 /X/,
  8555. Courier
  8556.     °dONLNd)<4d(PZ    USES°dONLNd    3<>Ø*
  8557.       AppleTalk, Files;°dONLNd&G<Ri*        CONST°dONLNd0Q<\Õ*
  8558.       { AFP version numbers }°dONLNdN[<f    *
  8559. )      AFPVer1_1 = 1;  { AFP version 1.1 }°dONLNdxe<p    *
  8560. )      AFPVer2_0 = 2;  { AFP version 2.0 }°dONLNd¢o<z    *
  8561. )      AFPVer2_1 = 3;  { AFP version 2.1 }°dONLNd—É<éh*<      AFPSVolInfo = 124;  { server volume information call }°dONLNdó<¢d*    TYPE°dONLNd°<¨‹*
  8562.        GetVolSessInfoRec = RECORD°dONLNd=´<∂r*
  8563. >          sessAFPVersion: Integer;        {AFP version number}°dONLNd|µ<¿ê*
  8564. D          sessReferenceNumber: Integer;   {session reference number}°dONLNd¡ø< Å*
  8565. A          sessAFPVolID: Integer;          {AFP volume identifier}°dONLNd…<‘ã*
  8566. C          sessServerAddress: AddrBlock;   {server internet address}°dONLNdG”<fiö*
  8567. F          sessUAMType: Integer;           {user authentication method}°dONLNdé›<Ëã*
  8568. C          sessUserNamePtr: StringPtr;     {ptr to user name string}°dONLNd“Á<ÚÆ*
  8569. J          sessVolIconPtr: Ptr;            {ptr to server volume icon/mask}°dONLNdÒ<¸Ω*
  8570. M          sessWhereStringPtr: StringPtr;  {ptr to "where" information string}°dONLNdk˚<x*
  8571.         END;°dONLNd}<@*4    FUNCTION GetVolSessionInfo (theVRefNum: Integer;°dONLNd≤<$Ü*
  8572. B                 VAR theVolSessInfoRec: GetVolSessInfoRec): OSErr;°dONLNdı#<.s*
  8573.       CONST°dONLNd-<86*
  8574. 2        TSigWord = $4244; { HFS volume signature }°dONLNd47<Bi*
  8575.           VAR°dONLNd>A<Læ*
  8576.         pb: ParamBlockRec;°dONLNdYK<Vπ*
  8577.         vcbPtr: QElemPtr;°dONLNdsU<`ı*
  8578. %        afpTranslatorRefNum: Integer;°dONLNdô_<jõ*
  8579.         err: OSErr;°dONLNd≠i<ti*
  8580.         BEGIN°dONLNd∑s<~"*
  8581. .      { get the .AFPTranslator driver refNum }°dONLNdÊ}<àw*
  8582. ?      err := OpenDriver('.AFPTranslator', afpTranslatorRefNum);°dONLNd&á<íæ*
  8583.       IF err <> noErr THEN°dONLNdAë<ú*
  8584. *        BEGIN { couldn't open the driver }°dONLNdlõ<¶Î*
  8585. #          GetVolSessionInfo := err;°dONLNdê•<∞Ê*
  8586. "          Exit(GetVolSessionInfo);°dONLNd≥Ø<∫x*
  8587.         END;°dONLNd≈√<ŒO*7      { find the VCB with the volume reference number }°dONLNd˝Õ<ÿï*
  8588. E      QHdrPtr(vcbPtr) := GetVCBQHdr;  { pointer to VCB queue header }°dONLNdC◊<‚Å*
  8589. A      vcbPtr := QHdrPtr(vcbPtr)^.qHead;  { pointer to first VCB }°dONLNdÖ·<Ï“*
  8590.       WHILE (vcbPtr <> NIL) DO°dONLNd§Î<ˆ}*
  8591.  
  8592.         BEGIN°dONLNd≤ı<≥*
  8593. K          IF VCB(vcbPtr^).vcbSigWord = TSigWord THEN { must be HFS volume }°dONLNd˛ˇ<
  8594. T*
  8595. 8            IF VCB(vcbPtr^).vcbVRefNum = theVRefNum THEN°dONLNd7    <*
  8596. *              Leave;  { we found the VCB }°dONLNdb<Y*
  8597. 9          vcbPtr := vcbPtr^.vcbQElem.qLink;  { next VCB }°dONLNdú<(x*
  8598.         END;°dONLNd©'<2»*
  8599.       IF (vcbPtr = NIL) THEN°dONLNdΔ1<<*
  8600. +        BEGIN  { couldn't find the volume }°dONLNdÚ;<F˙*
  8601. &          GetVolSessionInfo := nsvErr;°dONLNdE<PÊ*
  8602. "          Exit(GetVolSessionInfo);°dONLNd<O<Zx*
  8603.         END;°dONLNdNc<nm*=      { make the status call to get the volume session info }°dONLNdåm<xå*
  8604.       WITH pb DO°dONLNdùw<Ç}*
  8605.  
  8606.         BEGIN°dONLNd´Å<å*
  8607. *          ioRefNum := afpTranslatorRefNum;°dONLNd÷ã<ñ‹*
  8608.            csCode := AFPSVolInfo; ¡X¡
  8609. *$NW 16 - Borrowed AFP Sessions(÷5) of 8(ÏZM.NW.BorrowedAFPˇl◊#ˇ ˇˇˇˇ#◊ 
  8610. IR,Times
  8611. .+6-Macintosh Technical Notes /4/˘,
  8612. Courier
  8613.     °dONLNd(∏*           ioMisc := Ptr(vcbPtr);°dONLNd!'2Â*
  8614. )          ioBuffer := @theVolSessInfoRec;°dONLNdK1<?*
  8615. ;          ioReqCount := LongInt(sizeof(GetVolSessInfoRec));°dONLNdá;FT*
  8616.         END;°dONLNdîEP*
  8617. 0      GetVolSessionInfo := PBStatus(@pb, FALSE);°dONLNd≈OZ@*
  8618.     END;°dONLNd”cn?*;    FUNCTION DoGetVolSessionInfo (vRefNum: Integer): OSErr;°dONLNdmxE*
  8619.           VAR°dONLNdwÇw*
  8620.         err: OSErr;°dONLNd-ÅåÙ*
  8621. ,        myVolSessInfoRec: GetVolSessInfoRec;°dONLNdZãñ©*
  8622.         myIconHandle: Handle;°dONLNdxï†ö*
  8623.         myUserName: Str31;°dONLNdìü™Æ*
  8624.         myWhereString: Str255;°dONLNd≤©¥E*
  8625.         BEGIN°dONLNdº≥æ:*
  8626. :      err := GetVolSessionInfo(vRefNum, myVolSessInfoRec);°dONLNd˜Ω»ï*
  8627.       IF err = noErr THEN°dONLNd«“Y*
  8628.  
  8629.         BEGIN°dONLNd—‹¬*
  8630. "          WITH myVolSessInfoRec DO°dONLNdB€Êm*
  8631.             BEGIN°dONLNdTÂ+*
  8632. 7              { copy user name into a string variable }°dONLNdåÔ˙˘*
  8633. -              myUserName := sessUserNamePtr^;°dONLNdøI*=              { allocate a handle and move the icon into it }°dONLNd˝
  8634. 0*
  8635. 8              myIconHandle := NewHandle(kLargeIconSize);°dONLNd6"‡*
  8636. (              IF myIconHandle = NIL THEN°dONLNd_!,Å*
  8637.                 BEGIN°dONLNdu+6*
  8638. 2                  DoGetVolSessionInfo := MemError;°dONLNd®5@Ù*
  8639. ,                  Exit(DoGetVolSessionInfo);°dONLNd’?J|*
  8640.                 END;°dONLNdÍIT{*
  8641. G              BlockMove(sessVolIconPtr, myIconHandle^, kLargeIconSize);°dONLNd7]hv*F              { copy where information string into a string variable }°dONLNd~gr*
  8642. 3              myWhereString := sessWhereStringPtr^;°dONLNd∑{Ü£*O              { at this point, you can use all of the information just copied }°dONLNdÖêä*
  8643. J              { from myGetVolSessInfoRec or still in myGetVolSessInfoRec }°dONLNdWô§Â*)              DisposHandle(myIconHandle);°dONLNdÅ£Æh*
  8644.             END;°dONLNdí≠∏T*
  8645.         END;°dONLNdü∑¬Ω*
  8646. !      DoGetVolSessionInfo := err;°dONLNd¡¡Ã@*
  8647.     END;
  8648. °dONLNd ◊„    *(Session Borrowing Rules and Restrictions°dONLNdÛÔ˚L*Warning:°dONLNd¸Ô`˚é)H@The restrictions listed in this Note must be observed when your °dONLNd<Ôé˚∂(¨program°dONLNdD˚`ã(#~:borrows an AFP session owned by the Macintosh File System.°dONLNd :(<68There is a good reason why Apple has not documented the °dONLNd∑:á(<X AFPSVolInfo°dONLNd¬á æ)M
  8649.  status call °dONLNdœæ ⁄)7in the°dONLNd÷ ,3(H6past. °dONLNd‹ 3,⁄)WAFP file servers differentiate users by their sessions and the AppleShare external file°dONLNd4,8Û(T6+system makes certain assumptions about AFP °dONLNd_,Û8⁄)€1volumes (and their contents) that it has open. If°dONLNdë8DÃ(`6Sthe session owned by the Macintosh File System is used improperly, you can confuse °dONLNd‰8ÃD⁄(`Íthe°dONLNdËDPÇ(l6GAppleShare external file system or the file server. The basic rule you °dONLNd/DÇP⁄(l†should use when°dONLNd?P\(x64borrowing an AFP session owned by the file system is°dONLNdth*tó+If it can be done with °dONLNdãhót™)m6File Manager functions, use the File Manager functions°dONLNd¡h™t∂(ê»—°dONLNd¬t*ÄI(úHdon’t  °dONLNd…tIÄé)use AFP calls. ¡4¡˘
  8650. (÷66) of 8(÷qNW 16 - Borrowed AFP Sessions+0M.NW.BorrowedAFPˇ‚◊#ˇ ˇˇˇˇ#◊ 
  8651. IR,Times
  8652. .+Z-Developer Support Center(-€September 1992 /X/
  8653. °dONLNd<)ç(EZThat means you °dONLNdç)˛)QJshouldn’t open or close volumes, directories, files, or a volume’s desktop°dONLNdZ)<5k(QZ
  8654. database, °dONLNdd)k5˛)/Tyou  shouldn’t use calls that require a file or desktop database to be open, and you°dONLNdπ5<A…(]ZPdefinitely should not close the AFP session. If you need to do any of those AFP °dONLNd    5…A˛(]Á operations,°dONLNdA<M«(iZQyou should use the .XPP driver to open your own AFP session with the file server.°dONLNdgY<eï*The following is a °dONLNdzYïe˛)YLlist of AFP calls that are safe to use with a session borrowed from the file°dONLNd«e<qÉ(çZBsystem. For each AFP call, there’s an description of what you can °dONLNd    eÉq˛(ç°do with the call that you°dONLNd#q<}(ôZ*cannot do with the File Manager functions.,
  8655. Courier°dONLNdNâ<ïê* afpGetSParms°dONLNd[äÃñj)ê"This call can be used to retrieve °dONLNd}äjñ˛)ûthe server time and the list of°dONLNdùñâG(æÍserver volumes. For each °dONLNd∂ñG¢˛){%volume, you also can determine if the°dONLNd‹¢ÃÆ˝( Í
  8656. volume is °dONLNdÊ¢˝Æ˛)13password-protected and if the volume contains Apple°dONLNdÆÃ∫T(÷ÍII configuration information.°dONLNd8∫<Δû(„ZafpSetVolParms°dONLNdGªÃ«’)ê9This call can be used to set the backup date of a volume.°dONLNdÅ«<”≥(ZafpChangePassword°dONLNdì»Ã‘ƒ)ê4This call can be used to change the user’s password.°dONLNd»‘<‡û(˝ZafpGetUserInfo°dONLNd◊’÷„)ê<This call can be used to retrieve the specified user’s user °dONLNd’„·˛(˝ID or°dONLNd·ÃÌ#(    Íprimary group ID.°dONLNd+Ì<˘ó(Z
  8657. afpGetSrvrMsg°dONLNd9ÓÃ˙
  8658. )êThis call can °dONLNdGÓ
  8659. ˙˛)>3be used to retrieve the current greeting message or°dONLNd{˙Ù("Í/server message. This call is only supported by °dONLNd™˙™˛)fiAFP 2.1 servers.°dONLNdªÃ„(.Í;Note: the server message may not be applicable to the user.°dONLNd˜<∫(;ZafpMiscUserCommand°dONLNd
  8660. Ãl)êreserved for developer use. °dONLNd&l˛)†See Technical Note #323,°dONLNd?Ã+E(GÍ“Arbitrating Use °dONLNdPE+˛)yof afpMiscUserCommand and°dONLNdj+Ã7,(SÍafpMiscUserWrite.”°dONLNd}7<C¨(`ZafpMiscUserWrite°dONLNdé8ÃDl)êreserved for developer use. °dONLNd™8lD˛)†See Technical Note #323,°dONLNd√DÃPE(lÍ“Arbitrating Use °dONLNd‘DEP˛)yof afpMiscUserCommand and°dONLNdÓPÃ\,(xÍafpMiscUserWrite.”°dONLNdh<t(êZ0The list continues. However, these calls should °dONLNd1ht˛)„-be used only when you need to retrieve or set°dONLNd_t<ĸ(úZ]information (such as ProDOS information) that is inaccessible through File Manager functions.°dONLNdΩå<òê* afpEnumerate°dONLNd çÃô¥)ê0This call can be used to list the contents of a °dONLNd˙ç¥ô˛)Ëdirectory when°dONLNd    ôÕö(¡Í+either ProDOS information or specific file °dONLNd4ôö•˛)Œor directory attribute°dONLNdK•ñy(ÕÍinformation is needed. For all °dONLNdj•y±˛)≠other purposes, the File°dONLNdÉ≤Ãæ(⁄Í
  8661. Manager’s °dONLNdç±ΩU)5 PBGetCatInfo°dONLNdô≤UæÕ)T function should be used.°dONLNd≥æ< û(ÁZafpGetVolParms°dONLNd¬øÃÀj)ê"This call can be used to retrieve °dONLNd‰øjÀ˛)ûthe parameters for a particular°dONLNdÀÃ◊Ú(ÛÍserver °dONLNd ÀÚ◊˛)&-volume. For most purposes, the File Manager’s°dONLNd9◊Ä(Í PBHGetVInfo°dONLNdDÿ‰µ)M! function should be used instead.°dONLNdf‰<û(
  8662. ZafpSetDirParms°dONLNduÂÃÒ‘)ê8This call can be used to set parameters for a specified °dONLNd≠Â‘Ò˛(
  8663. Ú    directory°dONLNd∑ÒÃ˝(Í when either °dONLNd√Ò˝˛)<2ProDOS information or specific directory attribute°dONLNdˆ˝Ã    :(%Íinformation must be °dONLNd    
  8664. ˝:    ˛)n%set. For all other purposes, the File°dONLNd    0
  8665. Ã(2Í
  8666. Manager’s °dONLNd    :    U)5 PBSetCatInfo°dONLNd    F
  8667. UÕ)T function should be used.°dONLNd    `<"•(?ZafpSetFileParms°dONLNd    pÃ#
  8668. )êThis call can °dONLNd    ~
  8669. #˛)>3be used to set parameters for a specified file when°dONLNd    ≤#Ã/_(KÍeither ProDOS information or °dONLNd    œ#_/˛)ì#specific file attribute information°dONLNd    Û/Ã;ö(WÍ%must be set. For all other purposes, °dONLNd
  8670. /ö;˛)Œthe File Manager’s°dONLNd
  8671. +;ÃG (dÍ PBSetCatInfo°dONLNd
  8672. 7< Hò)T function should be used.°dONLNd
  8673. QH<T•(qZafpGetFlDrParms°dONLNd
  8674. aIÃU6)êThis call can be used °dONLNd
  8675. wI6U˛)j*to retrieve the parameters for a specified°dONLNd
  8676. ¢UÃaR(}Ífile or directory when either °dONLNd
  8677. ¿URa˛)Ü#ProDOS information or specific file°dONLNd
  8678. ‰aÃmÊ(âÍ6or directory attribute information is needed. For all °dONLNd aÊm˛(âother°dONLNd  nÃz(ñÍpurposes, the °dONLNd .nz[)CFile Manager’s °dONLNd =m[yØ)L PBGetCatInfo°dONLNd InØz˛)T function should°dONLNd ZzÃÜÙ(¢Íbe used. ¡X¡
  8679. (÷ZNW 16 - Borrowed AFP Sessions(÷7) of 8(ÏZM.NW.BorrowedAFPˇn◊#ˇ ˇˇˇˇ#◊ 
  8680. IR,Times
  8681. .+6-Macintosh Technical Notes /4/˘,
  8682. Courier
  8683. °dONLNd)Å*afpSetFlDrParms°dONLNd®*ª)ê8This call can be used to set parameters for a specified °dONLNdHª*⁄(FŸfile or°dONLNdP*®6ˆ(RΔdirectory when °dONLNd_*ˆ6⁄)N-either ProDOS information or specific file or°dONLNdç6®Bf(^Δ%directory attribute information must °dONLNd≤6fB⁄)æbe set. For all other°dONLNd»C®OÎ(kΔpurposes, the °dONLNd÷CÎO7)CFile Manager’s °dONLNdÂB7Nã)L PBSetCatInfo°dONLNdÒCãO⁄)T function should°dONLNdO®[–(wΔbe used.°dONLNd gsÆ(è6RIf the AppleShare 3.0 (or later) Chooser extension is used with System 6, you can °dONLNd]gÆs⁄(èÃmake the°dONLNdfsï(õ6Qfollowing AFP 2.1 calls to an AFP 2.1 file server. These calls are not supported °dONLNd∑sï⁄(õ≥
  8684. by the System°dONLNd≈ãc(ß66 File Manager.°dONLNd’ó£s*
  8685. afpGetSrvrMsg°dONLNd„ò®§0)êSee description in list above.°dONLNd§∞e(Õ6 afpCreateID°dONLNd•®±)êThis call can be used to °dONLNd'•±⁄)w'create a unique file ID for a specified°dONLNdO±®Ωª(ŸΔfile.°dONLNdUΩ…e(Ê6 afpDeleteID°dONLNdaæ® é)ê2This call can be used to invalidate all instances °dONLNdìæé ⁄)Êof the specified°dONLNd§ ®÷Õ(ÚΔfile ID.°dONLNd≠÷‚l(ˇ6 afpResolveID°dONLNd∫◊®„∑)ê7This call can be used to return information (including °dONLNdÒ◊∑„⁄(ˇ’the file°dONLNd˙„®Ô=( Δ"location) of the specified file ID°dONLNdÔ˚à(6afpExchangeFiles°dONLNd.®¸Ê)êThis call can °dONLNd<ʸ⁄)>2be used to exchange the contents of two files on a°dONLNdo¸®Ô($Δserver volume.°dONLNd~l(16 afpCatSearch°dONLNdã    ®
  8686. )êThis call can be used °dONLNd°    
  8687. ⁄)e,to search a volume for files or folders that°dONLNdŒ®!(=Δmatch specified criteria.
  8688. °dONLNdË9Ha(d6
  8689. Conclusion
  8690. °dONLNdÛUa/*The °dONLNd˜T/`|) AFPSVolInfo°dONLNdU|aè)M9 status call to the .AFPTranslator driver returns useful °dONLNd;Uèa⁄(}≠information for°dONLNdKamq(â6Gdevelopers who need to access an AFP file server in ways not supported °dONLNdíaqm⁄(âèby the Macintosh File°dONLNd®myB(ï6System. °dONLNd∞mBy⁄)*THowever, the restrictions lists in this note must be observed to prevent problems on°dONLNdyÖ„(°6,the client Macintosh or the AFP file server.°dONLNd2©µÇ*0Further Reference: ‘4‘˘°dONLNdE∂*¬.+
  8691. •°dONLNdG∂<¬=)1Inside Macintosh, Volume V, The AppleTalk Manager°dONLNdy¬*Œ.(ÍH•°dONLNd{¬<Œ–)M.NW.afpMiscUserCommand°dONLNdìŒ*⁄.(ˆH•°dONLNdïŒ<⁄^);Inside AppleTalk, Second Edition, AppleTalk Filing Protocol°dONLNd—⁄*Ê.(H•°dONLNd”⁄<Êë)EAppleShare 3.0 Developer’s Kit, AppleTalk Filing Protocol Version 2.1 ¡4¡˘
  8692. (÷68) of 8(÷qNW 16 - Borrowed AFP Sessions+0M.NW.BorrowedAFPˇn◊#ˇ ˇˇˇˇ#◊°d WORDS †å°d WORDR…†Ç 
  8693. /ZÅ#
  8694.     0Ià:µú9"{    ˇˇˇˇˇˇˇˇ#†ƒ°d
  8695. ONLNf˛†å°d1drw2…-·_ġˇˇˇˇˇè°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˙ó@†ò,Times
  8696. .^ tK^ tK+]BNew Technical Notes†ô°ddrw2:°„†ó°d1drw2eÙġˇˇˇˇˇP°ñ x°ddrw2:°ddrw2:$°d4drw2:°öˇ˚ÄE¿†ò
  8697. Ä({ïDeveloper Support†ô°ddrw2:°„†ó°d`drw2-ÔˇˇˇˇˇˇKÔ- Z  ffZ°d1drw2 ¿˙ÈˇˇˇˇˇˇK°ñ x°ddrw2:°ddrw2:$°d4drw2:0°öˇÙĆò
  8698. 0(UÔ†ô°ddrw2:°„†ó°d1drw2ÔÊ˙ˇˇˇˇˇˇ°ñ x°ddrw2:°ddrw2:$°d4drw2: